﻿using NCalc;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;
using SolidWorksTools;
using SolidWorksTools.File;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using SwParaPlatform2.server;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Drawing;
using SwParaPlatform2.dlgRuleConfig;
using SwParaPlatform2.dlgUIConfig;
using SwParaPlatform2.logger;
using SwParaPlatform2.tools;
using System.Text.Json.Nodes;
using Newtonsoft.Json.Linq;
using System.Data.Odbc;


namespace SwParaPlatform2
{
    /// <summary>
    /// Summary description for SwParaPlatform2.
    /// </summary>
    [Guid("2f384d74-b0b5-4db7-a95a-b2f7ecf8025c"), ComVisible(true)]
    [SwAddin(
        Description = "SwParaPlatform2 description",
        Title = "SwParaPlatform2",
        LoadAtStartup = true
        )]
    public class SwParaPlatform2 : ISwAddin
    {
        private const string Version = "3.5.2";
        #region Local Variables
        private static SwParaPlatform2 instance;
        public static SwParaPlatform2 Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new SwParaPlatform2();
                }
                return instance;
            }
        }
        ISldWorks iSwApp = null;
        ICommandManager iCmdMgr = null;
        int addinID = 0;
        BitmapHandler iBmp;
        int registerID;
        private readonly ISwParaInterface _commonInterface;
        private MainForm configFormInstance = null;
        private bool bNeedReloadConfig = false;

        public const int mainCmdGroupID = 5;
        public const int mainItemID1 = 0;
        public const int mainItemID2 = 1;
        public const int mainItemID3 = 2;
        public const int flyoutGroupID = 91;

        string[] mainIcons = new string[6];
        string[] icons = new string[6];

        private static TaskpaneView taskPaneView;
        private static TaskPaneHost taskPaneHost;

        private static Dictionary<string, List<string>> dRecordFeatureTypes;

        //// P/Invoke declarations
        //[DllImport("kernel32.dll", SetLastError = true)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //static extern bool AllocConsole();

        //[DllImport("kernel32.dll", SetLastError = true)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //static extern bool FreeConsole();

        public Dictionary<string, object> dMainAssemblyComs; //装配体文件的部件、配合属性是否压缩
        public Dictionary<string, object> dSubComponentInfo; //各个部件文件的属性节点树

        public Dictionary<string, string> DimDict;
        public Dictionary<string, string> DimEquDict;
        public Dictionary<string, string> SupDict;
        public Dictionary<string, string> SupEquDict;
        public Dictionary<string, string> RepDict;
        public Dictionary<string, string> SpLineDict;

        public static Dictionary<string, double> CacheDimValue;
        public static Dictionary<string, bool> CacheSupState;

        public static List<string> HandleSupList;
        public static List<string> HandleDimList;
        public static List<string> HandleRepList;


        private static List<Dictionary<string, string>> LinkSearchList;
        private static Dictionary<string, string> PDMFileDict;

        private static Dictionary<string, string> Replace_Simple_Name; //替换之后，就无法用原本记录的Compname去寻找到对应obj了，需要在替换时记录一下

        //private HttpServerManager server;
        //private PythonCaller pythonCaller;
        private static string conversationid;

        private static void InitializeFeatureProperties()
        {
            // 修改这里，需要同步修改defines.CompressList
            dRecordFeatureTypes = new Dictionary<string, List<string>>
            {
                { "ICE", new List<string> { "Compress" } },
                { "Extrusion", new List<string> { "Compress" } },
                { "Fillet", new List<string> { "Compress" } },
                { "Shell", new List<string> { "Compress" } },
                { "FtrFolder", new List<string> { "Compress" } },
                { "Cut", new List<string> { "Compress" } },
                { "ExtruThin", new List<string> { "Compress" } },
                { "SMBaseFlange", new List<string> { "Compress" } },
                { "BaseBody", new List<string> { "Compress" } },
                { "LPattern", new List<string> { "Compress" } },
                { "LocalLPattern", new List<string> { "Compress" } },
                { "HoleWzd", new List<string> { "Compress" } },
                { "MirrorCompFeat", new List<string> { "Compress" } },
                { "MirrorPattern", new List<string> { "Compress" } },
                { "ProfileFeature", new List<string> { "Compress" } },
                { "Revolution", new List<string> { "Compress" } },
                { "Sweep", new List<string> { "Compress" } },
                { "CirPattern", new List<string> { "Compress" } },
                { "Rib", new List<string> { "Compress" } },
                { "Chamfer", new List<string> { "Compress" } },
                { "RefPlane", new List<string> { "Compress" } },
                { "ReferencePattern", new List<string> { "Compress" } },
                { "SolidBodyFolder", new List<string> { "Compress" } },
                { "SurfaceBodyFolder", new List<string> { "Compress" } },
                { "LocalCirPattern", new List<string> { "Compress" } },
                { "FlatPattern", new List<string> { "Compress" } },
                { "TemplateFlatPattern", new List<string> { "Compress" } },
                { "UnFold", new List<string> { "Compress" } },
                { "EdgeFlange", new List<string> { "Compress" } },
                 { "RefAxis", new List<string> { "Compress" } },
                 { "RefPoint", new List<string> { "Compress" } },
            };

            HandleSupList = new List<string>();
            HandleDimList = new List<string>();
            HandleRepList = new List<string>();

            CacheDimValue = new Dictionary<string, double>();
            CacheSupState = new Dictionary<string, bool>();
            Replace_Simple_Name = new Dictionary<string, string>();
        }

        #region Event Handler Variables
        Hashtable openDocs = new Hashtable();
        SolidWorks.Interop.sldworks.SldWorks SwEventPtr = null;
        #endregion

        #region Property Manager Variables
        public UserPMPage ppage = null;
        #endregion


        // Public Properties
        public ISldWorks SwApp
        {
            get { return iSwApp; }
        }
        public ICommandManager CmdMgr
        {
            get { return iCmdMgr; }
        }

        public Hashtable OpenDocs
        {
            get { return openDocs; }
        }

        #endregion

        #region SolidWorks Registration //SolidWorks 注册
        [ComRegisterFunctionAttribute]
        public static void RegisterFunction(Type t)
        {
            #region Get Custom Attribute: SwAddinAttribute
            SwAddinAttribute SWattr = null;
            Type type = typeof(SwParaPlatform2);

            foreach (System.Attribute attr in type.GetCustomAttributes(false))
            {
                if (attr is SwAddinAttribute)
                {
                    SWattr = attr as SwAddinAttribute;
                    break;
                }
            }

            #endregion

            try
            {
                Microsoft.Win32.RegistryKey hklm = Microsoft.Win32.Registry.LocalMachine;
                Microsoft.Win32.RegistryKey hkcu = Microsoft.Win32.Registry.CurrentUser;

                string keyname = "SOFTWARE\\SolidWorks\\Addins\\{" + t.GUID.ToString() + "}";
                Microsoft.Win32.RegistryKey addinkey = hklm.CreateSubKey(keyname);
                addinkey.SetValue(null, 0);

                addinkey.SetValue("Description", SWattr.Description);
                addinkey.SetValue("Title", SWattr.Title);

                keyname = "Software\\SolidWorks\\AddInsStartup\\{" + t.GUID.ToString() + "}";
                addinkey = hkcu.CreateSubKey(keyname);
                addinkey.SetValue(null, Convert.ToInt32(SWattr.LoadAtStartup), Microsoft.Win32.RegistryValueKind.DWord);
            }
            catch (System.NullReferenceException nl)
            {
                Debug.Print("There was a problem registering this dll: SWattr is null. \n\"" + nl.Message + "\"");
                System.Windows.Forms.MessageBox.Show("There was a problem registering this dll: SWattr is null.\n\"" + nl.Message + "\"");
            }

            catch (System.Exception e)
            {
                Debug.Print(e.Message);

                System.Windows.Forms.MessageBox.Show("There was a problem registering the function: \n\"" + e.Message + "\"");
            }
        }

        [ComUnregisterFunctionAttribute]
        public static void UnregisterFunction(Type t)
        {
            try
            {
                Microsoft.Win32.RegistryKey hklm = Microsoft.Win32.Registry.LocalMachine;
                Microsoft.Win32.RegistryKey hkcu = Microsoft.Win32.Registry.CurrentUser;

                string keyname = "SOFTWARE\\SolidWorks\\Addins\\{" + t.GUID.ToString() + "}";
                hklm.DeleteSubKey(keyname);

                keyname = "Software\\SolidWorks\\AddInsStartup\\{" + t.GUID.ToString() + "}";
                hkcu.DeleteSubKey(keyname);
            }
            catch (System.NullReferenceException nl)
            {
                Debug.Print("There was a problem unregistering this dll: " + nl.Message);
                System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: \n\"" + nl.Message + "\"");
            }
            catch (System.Exception e)
            {
                Debug.Print("There was a problem unregistering this dll: " + e.Message);
                System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: \n\"" + e.Message + "\"");
            }
        }

        #endregion

        #region ISwAddin Implementation   //ISwAddin 实现
        public SwParaPlatform2()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            _commonInterface = new SwParaInterface();

        }

        public bool ConnectToSW(object ThisSW, int cookie)
        {
            iSwApp = (ISldWorks)ThisSW;
            addinID = cookie;

            //Setup callbacks
            iSwApp.SetAddinCallbackInfo(0, this, addinID);

            Logger.Instance.MinLevel = LogLevel.Debug;
            Logger.Instance.FileSizeLimitBytes = 5 * 1024 * 1024L;   // 5 MB
            Logger.Instance.WriteToConsole = true;

            #region Setup the Command Manager
            iCmdMgr = iSwApp.GetCommandManager(cookie);
            //AddCommandMgr();
            #endregion

            #region Setup the Event Handlers
            SwEventPtr = (SolidWorks.Interop.sldworks.SldWorks)iSwApp;
            openDocs = new Hashtable();
            AttachEventHandlers();
            #endregion

            #region Setup Sample Property Manager
            AddPMP();
            #endregion

            CreateTaskPane();

            // Init Dict
            InitializeFeatureProperties();

            AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
            {
                Exception ex = (Exception)args.ExceptionObject;
                System.IO.File.WriteAllText(@"C:\Users\37127\Documents\unhandled_log.txt", ex.ToString());
                MessageBox.Show($"Unhandled exception: {ex.Message}\n{ex.StackTrace}");
            };




            return true;
        }

        public bool DisconnectFromSW()
        {
            RemoveCommandMgr();
            RemovePMP();
            DetachEventHandlers();
            Logger.Instance.Dispose();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(iCmdMgr);
            iCmdMgr = null;
            System.Runtime.InteropServices.Marshal.ReleaseComObject(iSwApp);
            iSwApp = null;
            //The addin _must_ call GC.Collect() here in order to retrieve all managed code pointers 
            GC.Collect();
            GC.WaitForPendingFinalizers();

            GC.Collect();
            GC.WaitForPendingFinalizers();

            return true;
        }
        private bool CheckComputerNameValid()
        {
            return true;
            List<string> ValidName = new List<string>
            {
                "KB",
                "LAPTOP-QAAGBDON",
                "DESKTOP-0VDQ67G",
                "YUXITECH-LXH",
            };
            string computerName = System.Environment.MachineName;

            if (ValidName.Contains(computerName))
            {
                return true;
            }
            MessageBox.Show("当前计算机没有使用宇喜参数化平台的权限，请联系技术人员");
            return false;
        }

        /// <summary>
        /// 创建初始化宇喜参数化平台的任务窗格，初始化界面控件与相关事件，并设置图标资源路径。
        /// </summary>
        private void CreateTaskPane()
        {
            if (CheckComputerNameValid())
            {
                try
                {
                    //记录进程
                    string tempPath = Path.Combine(Path.GetTempPath(), "canicon.png");
                    Image img = Properties.Resources.canicon;

                    // 保存图片到临时文件
                    img.Save(tempPath);
                    tempPath = tempPath.Replace('\\', '/');
                    Logger.Instance.Log("当前插件版本：" + Version);
                    Logger.Instance.Log("临时文件保存路径：" + tempPath);

                    // 回调
                    taskPaneView = iSwApp.CreateTaskpaneView2(tempPath, $"宇喜参数化平台 {Version}");
                    taskPaneHost = (TaskPaneHost)taskPaneView.AddControl("SwParaPlatform2.TaskPaneHost", "");
                    taskPaneHost.SetSwApp(SwApp);

                    // 删除临时文件
                    if (File.Exists(tempPath))
                    {
                        File.Delete(tempPath);
                        Logger.Instance.Log("临时文件已删除");
                    }
                    else
                    {
                        Logger.Instance.Log("文件不存在，无法删除");
                    }

                    taskPaneHost.EditNowConfigClick += TaskPaneHost_EditNowConfigClick;//使用当前模型文件新建配置文件
                    taskPaneHost.EditSelectConfigClick += TaskPaneHost_EditSelectConfigClick; //选择模型文件并新建配置文件
                    taskPaneHost.OpenConfigFileClick += TaskPaneHost_OpenConfigFileClick; //打开已有配置文件
                    taskPaneHost.ChangeBtnClick += TaskPaneHost_ChangeBtnClick; //修改当前配置文件

                    taskPaneHost.TestBtnClick += TaskPaneHost_TestBtnClick;            // * 测试"按钮
                    taskPaneHost.DriveBtnClick += TaskPaneHost_DriveBtnClick; //驱动
                    //taskPaneHost.OpenWindowBtnClick += TaskPaneHost_OpenWindowBtnClick;
                    taskPaneHost.OpenWindowBtnClick += TaskPaneHost_OpenWindowBtnClick2;
                    taskPaneHost.CloseBtnClick += TaskPaneHost_CloseBtnClick;
                    taskPaneHost.SaveFileBtnClick += TaskPaneHost_SaveFileBtnClick;//保存当前文件改动
                    taskPaneHost.ShowMainForm += TaskPaneHost_ShowMainForm;

                    // ai
                    long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                    conversationid = $"{timestamp}_conversation";
                    Logger.Instance.Log($"当前时间戳（秒级）：{timestamp}");
                    taskPaneHost.CallModel += TaskPaneHost_CallModel;
                    taskPaneHost.CallModel2 += TaskPaneHost_CallModel2;
                    taskPaneHost.OnSearchOutPutFinish += TaskPaneHost_OnSearchOutPutFinish;
                    taskPaneHost.OpenSearchFile += TaskPaneHost_OpenSearchFile;

                    HttpRequest.OnDataReceived += HttpRequest_OnDataReceived;
                    HttpRequest.OnStopPolling += HttpRequest_OnStopPolling;

                    HttpRequest.OnDataReceived2 += HttpRequest_OnDataReceived2;

                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error in CreateTaskPane: {ex.Message}");
                }
            }

        }

        /// <summary>
        /// 使用当前打开的模型文档按键创建并保存配置文件，初始化路径追踪器，并保存建模树和方程式数据。/// 
        /// </summary>
        /// 
        [STAThread]
        private void TaskPaneHost_EditNowConfigClick()
        {
            try
            {
                SwAppMgr.Instance.SetSldApp(iSwApp);
                IModelDoc2 oActiveDoc = GetActiveDocument();
                //初始化SolidWorksPathUpdater 
                CreatePathUpdater();
                DataStore.Instance.sMainAssemName = oActiveDoc.GetTitle();
                string relativeMainFilePath = CreateWorkPath();
                SaveFileNameData(relativeMainFilePath);  // 保存文件路径数据到 XML 文件中
                SaveTreeViewData();//提取当前文档体的组件结构信息，并将其保存到内存中的 TreeView 数据结构中
                RecordEquationData(); //该方法没有使用
                ConnectSelectionNotify();
                // _commonInterface.PrintDictionary(DataStore.Instance.TreeViewData, 0);
                // 确保调用 Application.SetCompatibleTextRenderingDefault(false) 和 Application.Run(new MainForm()) 在程序入口点
                //RunMainForm();
            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"Error in TaskPaneHost_EditNowConfigClick: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }
        }  //拆分不了
        /// <summary>
        /// 打开文件并初始化相关插件数据、注册事件监听。/// 
        /// </summary>
        private void TaskPaneHost_EditSelectConfigClick()
        {
            try
            {
                SwAppMgr.Instance.SetSldApp(iSwApp);
                TaskPaneHost_CloseBtnClick();//关闭当前插件任务窗格
                IModelDoc2 oSelectDoc = OpenDocumentFromFileExplorer();//弹出文件选择器
                CreatePathUpdater();// 创建一个路径更新器
                if (oSelectDoc == null)
                    return;
                DataStore.Instance.sMainAssemName = oSelectDoc.GetTitle();
                string relativeMainFilePath = CreateWorkPath();
                SaveFileNameData(relativeMainFilePath);
                SaveTreeViewData();//提取当前文档体的组件结构信息，并将其保存到内存中的 TreeView 数据结构中
                RecordEquationData(); //该方法没有使用
                ConnectSelectionNotify();
                //_commonInterface.PrintDictionary(DataStore.Instance.TreeViewData, 0);
                // 确保调用 Application.SetCompatibleTextRenderingDefault(false) 和 Application.Run(new MainForm()) 在程序入口点
                //RunMainForm();



            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
                MessageBox.Show($"Error in TaskPaneHost_EditSelectConfigClick: {ex.Message}");
            }
        }//不可拆分
        /// <summary>
        /// 读取 UI 上输入的参数数据并应用到当前文档模型，实现模型尺寸或结构的自动更新。/// 
        /// </summary>
        private void TaskPaneHost_DriveBtnClick()
        {
            try
            {
                IModelDoc2 oActiveDoc = GetActiveDocument();
                if (oActiveDoc != null)
                {
                    DataStore.Instance.UIGridData = taskPaneHost.GetDataFromUIGrid();
                    DoDriveModel();
                }
                else
                {
                    MessageBox.Show("当前没有打开的模型文档");
                }

            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"Error in TaskPaneHost_DriveBtnClick: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }

        }
        /// <summary>
        /// 更改”按钮点击事件，连接 SolidWorks 的选择事件监听器。/// 
        /// </summary>
        private void TaskPaneHost_ChangeBtnClick()
        {
            SwAppMgr.Instance.SetSldApp(iSwApp);
            ConnectSelectionNotify();
        }

        private void TaskPaneHost_ShowMainForm() {
            OnFinishConfig(this,true,true);
        }
        /// 打开配置主窗口（MainForm）用于配置驱动参数，并初始化当前模型路径、变量、路径更新器等相关数据。/// 
        /// </summary>
        private void TaskPaneHost_OpenWindowBtnClick2()
        {
            try
            {
                if (configFormInstance == null || configFormInstance.IsDisposed)//检查配置窗口是否已存在或已被关闭
                {
                    if (!string.IsNullOrEmpty(DataStore.Instance.sWorkingPath))
                    {
                        bNeedReloadConfig = true;
                        // 避免重开，此处先不打包提取到的数据
                        taskPaneHost.SavaConfig(false);
                        IModelDoc2 oActiveDoc = GetActiveDocument();
                        CreatePathUpdater();
                        DataStore.Instance.sMainAssemName = oActiveDoc.GetTitle();
                        //SaveTreeViewData();
                        // SaveFileNameData();
                        RecordEquationData();//该方法没有使用
                        RunMainForm();
                        bNeedReloadConfig = false;

                    }
                    else
                    {
                        MessageBox.Show("当前并未加载任何配置");
                    }
                }
                else
                {
                    configFormInstance.Activate();
                }

            }
            catch(Exception ex)
            {
                Logger.Instance.Log($"Error in TaskPaneHost_ChangeBtnClick: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }
            
        }

        private void TaskPaneHost_TestBtnClick()
        {

        }
        /// <summary>
        /// “打开配置文件”的功能
        /// </summary>
        private void TaskPaneHost_OpenConfigFileClick()
        {
            try
            {
                SwAppMgr.Instance.SetSldApp(iSwApp);
                TaskPaneHost_CloseBtnClick();//关闭当前文档
                IModelDoc2 oActiveDoc = GetActiveDocument();//获取当前活动的 SolidWorks 文档
                string sSelectFile = _commonInterface.LoadAllData();
                if (!string.IsNullOrEmpty(sSelectFile))
                {
                    string sDocPath = DataStore.Instance.sDocPath;
                    if (oActiveDoc != null)
                    {
                        iSwApp.CloseDoc(oActiveDoc.GetTitle());
                        Marshal.ReleaseComObject(oActiveDoc);
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        //DataStore.Instance.sMainAssemName = oActiveDoc.GetTitle();
                        //SaveTreeViewData(oActiveDoc);

                    }

                    string sSelectPath = Path.GetDirectoryName(sSelectFile);
                    DataStore.Instance.sParentPath = sSelectPath;
                    string sWorkingPath = CreateWorkingPathByConfig(sSelectFile);
                    string sFullPath = Path.Combine(sWorkingPath, sDocPath);
                    
                    IModelDoc2 oSelectDoc = OpenDocument(sFullPath);
                    DataStore.Instance.sMainAssemName = oSelectDoc.GetTitle();
                    SaveTreeViewData();
                    CreatePathUpdater();
                    ConnectSelectionNotify();
                    // SaveFileNameData();
                    RecordEquationData();
                    OnFinishConfig(this, true, true);
                }
                //string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(sSelectFile);  // 获取文件名（不含后缀）
                //string destinationFolderPath = Path.Combine(Path.GetDirectoryName(sSelectFile), $"_{fileNameWithoutExtension}");
                //DeleteCachePath(destinationFolderPath);
            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
                MessageBox.Show($"打开当前项目出错: {ex.Message}");
            }
        }
        /// <summary>
        /// 彻底清理插件的临时数据、界面状态和模型引用，并关闭当前 SolidWorks 文件。
        /// </summary>
        private void TaskPaneHost_CloseBtnClick()
        {
            try
            {
                DisConnectSelectionNotify(); //解除选中监听
                taskPaneHost.ClearCurrentControlData(); //清理提取窗口数据
                taskPaneHost.HideCurrentControl(); //关闭提取窗口
                taskPaneHost.ClearDriveView(); //清理驱动窗口数据
                taskPaneHost.SetEditPartShow(false); //关闭驱动窗口

                DataStore.Reset(); //重置DataStore
                SolidWorksPathUpdater.Reset(); //重置路径更新器
                UIConfigModel.Reset(); //重置UI配置数据
                RuleConfigModel.Reset(); //重置规则配置数据

                //清理插件记录的其他数据
                dMainAssemblyComs = new Dictionary<string, object>(); //装配体文件的部件、配合属性是否压缩
                dSubComponentInfo = new Dictionary<string, object>(); //各个部件文件的属性节点树
                DimDict = new Dictionary<string, string>();
                DimEquDict = new Dictionary<string, string>();
                SupDict = new Dictionary<string, string>();
                SupEquDict = new Dictionary<string, string>();
                RepDict = new Dictionary<string, string>();
                SpLineDict = new Dictionary<string, string>();
                CacheDimValue = new Dictionary<string, double>();
                CacheSupState = new Dictionary<string, bool>();
                HandleSupList = new List<string>();
                HandleDimList = new List<string>();
                HandleRepList = new List<string>();
                Replace_Simple_Name = new Dictionary<string, string>();

                ModelDoc2 modelDoc2 = (ModelDoc2)iSwApp.ActiveDoc;
                if(modelDoc2 != null)
                {
                    iSwApp.CloseDoc(modelDoc2.GetTitle());
                    Marshal.ReleaseComObject(modelDoc2);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                    

            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"Error in TaskPaneHost_ChangeBtnClick: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }
        }
        /// <summary>
        /// 保存当前活动 SolidWorks 文档
        /// </summary>
        private void TaskPaneHost_SaveFileBtnClick()
        {
            int errors = 0;
            int warnings = 0;
            ModelDoc2 ActiveDoc = iSwApp.ActiveDoc;
            if(ActiveDoc != null)
            {
                ActiveDoc.Save();//保存当前活动文档，
                string DocPath = ActiveDoc.GetPathName();
                int iDocType = ActiveDoc.GetType();
                iSwApp.CloseDoc(ActiveDoc.GetTitle());
                Marshal.ReleaseComObject(ActiveDoc);
                GC.Collect();
                GC.WaitForPendingFinalizers();

                XmlHandler.CompressFolderToZip();//夹压缩成 ZIP 文件

                IModelDoc2 modelDoc = iSwApp.OpenDoc6(DocPath, iDocType,
                    (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", ref errors, ref warnings);
                SaveTreeViewData();//保存树形视图数据
            }
        }
        //主要是捕获异常，展示错误信息和记录日志
        async void TaskPaneHost_CallModel(string CallMsg)
        {
            try
            {
                // ✅ 2. 调用 `HttpRequest.Run()` 方法
                await Main(CallMsg);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error in TaskPaneHost_CallModel: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }
            
        } 

        async void TaskPaneHost_CallModel2(string CallMsg)
        {
            try
            {
                // ✅ 2. 调用 `HttpRequest.Run()` 方法
                await Main2(CallMsg);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error in TaskPaneHost_CallModel: {ex.Message}");
                Logger.Instance.Log($"Stack Trace: {ex.StackTrace}");
            }

        }
        /// <summary>
        /// 取搜索结果列表中最多前三条，插入到任务面板中，清空搜索结果列表
        /// </summary>
        private void TaskPaneHost_OnSearchOutPutFinish()
        {
            foreach(Dictionary<string, string> Name_2_Path in LinkSearchList.Take(3).ToList())
            {
                taskPaneHost.InsertNewLink(Name_2_Path);
            }
            taskPaneHost.AddQuot();//追加一个换行
            taskPaneHost.AddQuot();
            taskPaneHost.AddQuot();
            LinkSearchList = new List<Dictionary<string, string>>();
        }
        /// <summary>
        /// 通过路径打开零件或装配体文件 
        /// </summary>
        private void TaskPaneHost_OpenSearchFile(string fileName)
        {
            int iDocType = 1;
            int errors = 0;
            int warnings = 0;
            if (fileName.EndsWith(".sldprt", StringComparison.OrdinalIgnoreCase))
            {
                iDocType = (int)swDocumentTypes_e.swDocPART;
            }
            else if(fileName.EndsWith(".sldasm", StringComparison.OrdinalIgnoreCase))
            {
                iDocType = (int)swDocumentTypes_e.swDocASSEMBLY;
            }
            else
            {
                MessageBox.Show("不支持的文件类型");
                return;
            }
            IModelDoc2 modelDoc = iSwApp.OpenDoc6(fileName, iDocType,
                    (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", ref errors, ref warnings);
        }//工具（solidwork）

        static async Task Main(string CallMsg)
        {
            Dictionary<string, Dictionary<string, object>> dUIConfigData = UIConfigModel.Instance.GetGridDataDict();
            var paramDict = CommonTools.ExtractParamDict(dUIConfigData);
            //    var paramDict = new Dictionary<string, Dictionary<string, object>>
            //{
            //    { "长度", new Dictionary<string, object> { { "最大值", 50000 }, { "最小值", 20 }, { "默认值", 1200 }, { "可选值", "" } } },
            //    { "宽度", new Dictionary<string, object> { { "最大值", 50000 }, { "最小值", 20 }, { "默认值", 600 }, { "可选值", "" } } },
            //    { "高度", new Dictionary<string, object> { { "最大值", 50000 }, { "最小值", 20 }, { "默认值", 800 }, { "可选值", "" } } }
            //};

            // ✅ 2. 调用 `HttpRequest.Run()` 方法
            await HttpRequest.Run(CallMsg, paramDict, conversationid);
        }

        static async Task Main2(string CallMsg)
        {
            Dictionary<string, Dictionary<string, object>> dUIConfigData = dlgUIConfig.UIConfigModel.Instance.GetGridDataDict();
            List<string> paramList = CommonTools.GetFileNames(SearchAllFile());
            LinkSearchList = new List<Dictionary<string, string>>();
            await HttpRequest.Run2(CallMsg, paramList, conversationid);
        }
        /// <summary>
        /// 用于处理从服务器或外部服务返回的数据 
        /// </summary>
        private void HttpRequest_OnDataReceived(Dictionary<string, object> datadict)
        {
            Logger.Instance.Log("🎯 外部收到数据：");

            foreach (var kv in datadict)
            {
                Logger.Instance.Log($" - {kv.Key}: {kv.Value}");
            }
            if ((bool)datadict["Fail"])
            {
                taskPaneHost.AddModelInput("网络繁忙，请重试");
            }
            else
            {
                //文本输出
                string Think = (string)datadict["think"];
                taskPaneHost.AddModelInput(Think);
                taskPaneHost.ReActiveTextBox();

                //字典驱动
                var data = JsonConvert.DeserializeObject<Dictionary<string, object>>((string)datadict["content"]);
                Dictionary<string, Dictionary<string, object>> dUIConfigData = dlgUIConfig.UIConfigModel.Instance.GetGridDataDict();
                Dictionary<string, object> DriveData = CommonTools.ConvertDriveDataUnits(data, dUIConfigData); ;
                DataStore.Instance.UIGridData = DriveData;
                DoDriveModel();
            }

        }
        /// <summary>
        /// 处理从服务器或外部服务返回的数据，主要通过路径打开零件或装配体文件 
        /// </summary>
        private void HttpRequest_OnDataReceived2(Dictionary<string, object> datadict)
        {
            Logger.Instance.Log("🎯 外部收到数据2：");

            foreach (var kv in datadict)
            {
                Logger.Instance.Log($" - {kv.Key}: {kv.Value}");
            }
            if ((bool)datadict["Fail"])
            {
                taskPaneHost.AddModelInput2("网络繁忙，请重试");
            }
            else
            {
                //文本输出
                string Think = (string)datadict["think"];
                taskPaneHost.AddModelInput2(Think);
                taskPaneHost.ReActiveTextBox();

                //生成链接
                var list = ((JArray)datadict["content"]).ToObject<List<string>>();
                foreach (var item in list)
                {
                    if (PDMFileDict.ContainsKey(item))
                    {
                        Logger.Instance.Log($"name - {item}");
                        Logger.Instance.Log($"path - {PDMFileDict[item]}");
                        LinkSearchList.Add(new Dictionary<string, string>
                    {
                        { item, PDMFileDict[item] },
                    });
                    }
                }
            }

        }
        /// <summary>
        ///在 HTTP 轮询结束时，重新激活界面上的两个输入框 
        /// </summary>
        private void HttpRequest_OnStopPolling()
        {
            taskPaneHost.ReActiveTextBox();
        }
        /// <summary>
        /// 搜索SolidWorks文件
        /// </summary>
        public static List<string> SearchAllFile()
        {
            //string folderPath = @"D:\37127\Documents\参数化测试\弘道换热水箱\芯体 - 副本_3\model";
            string folderPath = CommonTools.ReadPathFromFile();

            List<string> solidWorksFiles = Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories)
                .Where(file => file.EndsWith(".sldprt", StringComparison.OrdinalIgnoreCase)
                            || file.EndsWith(".sldasm", StringComparison.OrdinalIgnoreCase))
                .ToList();

            foreach (var file in solidWorksFiles)
            {
                Console.WriteLine(file);
            }
            PDMFileDict = CommonTools.GetFileNamePathDictionary(solidWorksFiles);
            return solidWorksFiles;
        }
        /// </summary>
        /// 提取当前文档体的组件结构信息，并将其保存到内存中的 TreeView 数据结构中
        /// </summary>
        private void SaveTreeViewData()
        {
            IModelDoc2 oActiveDoc = GetActiveDocument();
            dSubComponentInfo = new Dictionary<string, object>();//初始化字典
            var componentsDict = ProcessDocument(oActiveDoc, null);//
            //Logger.Instance.Log("run SaveTreeViewData");
            dMainAssemblyComs = GetAssemblyComponentsAndMates();

            DataStore.Instance.TreeViewData = componentsDict;
            //DataStore.Instance.MainAssemblyData = DataStore.Instance.ConvertInputData(dMainAssemblyComs);
            if (oActiveDoc.GetTitle().EndsWith(".sldasm", StringComparison.OrdinalIgnoreCase))//判断是否是装配体
            {
                var dFirstSubObj = DataStore.Instance.TreeViewData["SubComp"];//获取树结构中最上层的 "SubComp" 节点
                if (dFirstSubObj is Dictionary<string, object> dFirstSubDict)
                {
                    var dSecondSubObj = dFirstSubDict[oActiveDoc.GetTitle()];
                    if (dSecondSubObj is Dictionary<string, object> dSecondSubDict)
                    {
                        var dThridObj = dSecondSubDict["SubComp"];
                        if (dThridObj is Dictionary<string, object> dThridDict)
                        {
                            dThridDict[oActiveDoc.GetTitle()] = dMainAssemblyComs;
                        }
                    }
                }
            }
            DataStore.Instance.InitParentChildMap();//初始化父子映射表
            taskPaneHost.RefreshTreeView();//刷新界面
        }

        /// 保存文件路径数据到 XML 文件中
        /// </summary>
        public void SaveFileNameData(string relativeMainFilePath)
        {
            string filePath = XmlHandler.GetFilePath();
            string rootElementName = "Path";
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;
            Dictionary<string, object> dFileName = new Dictionary<string, object>
            {
                {"FilePath",  relativeMainFilePath},
            };//构建一个字典，将文件的路径信息保存

            Dictionary<string, Dictionary<string, object>> dFilePath = new Dictionary<string, Dictionary<string, object>>
            {
                {"FileName",  dFileName},
            };

            int errors = 0;
            int warnings = 0;
            ModelDoc2 ActiveDoc = iSwApp.ActiveDoc;
            string DocPath = Path.Combine(DataStore.Instance.sWorkingPath, relativeMainFilePath);

            ///关闭当前 SolidWorks 文档，且重新打开文档
            if (ActiveDoc != null)
            {
                int iDocType = ActiveDoc.GetType();// 记录当前文档类型（零件、装配体、工程图）
                iSwApp.CloseDoc(ActiveDoc.GetTitle());// 关闭当前模型 ？
                Marshal.ReleaseComObject(ActiveDoc); // 释放 COM 资源
                GC.Collect();
                GC.WaitForPendingFinalizers();// 等待资源释放完成
                XmlHandler.SaveAndPackConfigFile(filePath, dFilePath, rootElementName); //保存配置到 XML
                IModelDoc2 modelDoc = iSwApp.OpenDoc6(DocPath, iDocType,
                    (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", ref errors, ref warnings); //重新打开文档：
            }
        }//工具（solidworks）

        /// 保存文件路径数据到 XML 文件中
        /// </summary>
        public static void DeleteCachePath(string configFolderPath)
        {
            if (Directory.Exists(configFolderPath))
            {
                Directory.Delete(configFolderPath, true);  // 递归删除文件夹
            }
        }//工具（待定）
        //创建 SolidWorksPathUpdater 实例
        private void CreatePathUpdater()
        {
            // 创建 SolidWorksPathUpdater 实例
            IModelDoc2 activedoc = GetActiveDocument();
            SolidWorksPathUpdater.Initialize(iSwApp);
        }//工具（solidworks）
        /// <summary>
        ///在当前文档目录下创建新文件，并且复制当前文档的主模型文件（及其子零件）
        /// </summary>
        /// 
        private string CreateWorkPath()
        {
            // 创建 SolidWorksPathUpdater 实例
            IModelDoc2 activedoc = GetActiveDocument();
            var updater = SolidWorksPathUpdater.Instance;

            // 打开文件管理器选择目标文件夹
            string targetDirectory = updater.CreateHiddenConfigDirectory(activedoc);//在当前文档目录下创建隐藏的文件包，并返回其路径
            DataStore.Instance.sWorkingPath = targetDirectory; //这个目标路径保存到全局变量中

            //
            DataStore.Instance.sWorkingPath_New = targetDirectory;

            if (!string.IsNullOrEmpty(targetDirectory))
            {
                // 执行复制操作并修改引用路径
                string relativeMainFilePath = updater.CopyAndModifyReferences(targetDirectory, activedoc.GetPathName(), "model");

                // 输出相对路径
                Logger.Instance.Log($"主文件的相对路径: {relativeMainFilePath}");

                return relativeMainFilePath;
            }
            return "";
        }//工具（solidworks）

        [STAThread]
        private void RunMainForm()
        {

            configFormInstance = new MainForm();
            configFormInstance.FormClosedEvent += OnFinishConfig;
            // 在窗口显示后执行逻辑
            configFormInstance.Shown += (sender, e) =>
            {
                // 在窗口显示后执行的逻辑
                ReloadAllData();
            };

            Application.Run(configFormInstance);
        }

        [STAThread]

        //用于判断窗体是“代码主动关闭”还是“用户手动关闭
        private void OnFinishConfig(object sender, bool isProgrammaticallyClosed, bool bNeedCloseCurrentControl = true)
        {
            // 在Form关闭后执行的方法
            if (isProgrammaticallyClosed)
            {
                taskPaneHost.InitDataView();//重新初始化数据视图
                if (bNeedCloseCurrentControl)
                {
                    taskPaneHost.HideCurrentControl();//隐藏当前活动控制控件
                }
                taskPaneHost.SetEditPartShow(true);

            }
            else
            {
                // 这是用户点击了右上角的“×”按钮关闭窗体
                Logger.Instance.Log("窗体是通过右上角的'×'关闭的。");
            }
        }
        //在窗体显示出来重新加载所有配置数据
        private void ReloadAllData()
        {
            if (bNeedReloadConfig)
            {
                _commonInterface.ReloadAllData();
            }
        }
        /// <summary>
        ///将当前活动文件打包到指定文件夹
        /// </summary>
        /// 
        public void PackAndGoAssembly(string destinationDir)
        {
            // 获取当前活动文档
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;

            try
            {
                // 获取PackAndGo对象
                PackAndGo packAndGo = (PackAndGo)activeDoc.Extension.GetPackAndGo();
                // 设置PackAndGo选项
                packAndGo.IncludeDrawings = true;//是否包含工程图文件
                packAndGo.IncludeSimulationResults = false;//是否包含仿真文件
                packAndGo.IncludeToolboxComponents = true;//是否包含 Toolbox 组件
                packAndGo.FlattenToSingleFolder = true;//是否将所有文件保存到一个扁平文件夹（而非保留子文件夹结构）
                packAndGo.SetSaveToName(true, destinationDir);//设置所有文件的目标保存位置

                // 获取文件列表
                object fileNames;
                object fileStatus;
                packAndGo.GetDocumentSaveToNames(out fileNames, out fileStatus);

                // 执行PackAndGo
                int[] statuses = (int[])activeDoc.Extension.SavePackAndGo(packAndGo);

                // 检查结果
                if (statuses != null && statuses.Length > 0)
                {
                    Logger.Instance.Log($"PackAndGo成功完成。输出路径 = {destinationDir}");
                }
                else
                {
                    Logger.Instance.Log($"PackAndGo失败。");
                }
            }
            catch(Exception ex)
            {
                Logger.Instance.Log($"获取PackAndGo对象失败： {ex.Message}");
                return;
            }
        }//工具（solidworks）【待定】
        // 
        private void CopyWorkingPathAfterDrive()
        {
            string fileNameWithoutExtension = Path.GetFileName(DataStore.Instance.sWorkingPath);//获取文件名
            string destinationFolderPath = Path.Combine(DataStore.Instance.sParentPath, fileNameWithoutExtension.Replace("_Config", ""));  // 解压后的文件夹路径
            destinationFolderPath = CommonTools.Instance.GetUniqueFolderPath(destinationFolderPath);//生成不重复的路径
            string destinationFolderPath2 = Path.Combine(destinationFolderPath, "model");
#if !DEBUG
            try
            {
                if(taskPaneHost.CanPackAndGo())
                    PackAndGoAssembly(destinationFolderPath2);
            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"尝试打包文件失败： {ex.Message}");
                MessageBox.Show($"尝试打包文件失败： {ex.Message}");
            }
#endif
        }//工具方法？

        //把一配置包（zip 文件）中解压到相应文件夹
        private string CreateWorkingPathByConfig(string zipFilePath)
        {
            //string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(zipFilePath).Replace("_Config", "");  // 获取文件名（不含后缀）
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(zipFilePath);
            string destinationFolderPath = Path.Combine(DataStore.Instance.sParentPath, $"_{fileNameWithoutExtension}");  // 解压后的文件夹路径
            if (Directory.Exists(destinationFolderPath))
            {
                Directory.Delete(destinationFolderPath, true);
            }
            //destinationFolderPath = GetUniqueFolderPath(destinationFolderPath);
            XmlHandler.ExtractZip(zipFilePath, destinationFolderPath);//创建文件夹，并且解压到目标文件夹
            //string modelFolder = Path.Combine(destinationFolderPath, "model");

            // 1. 删除路径 A 中的所有内容，除了 "model" 文件夹
            //DeleteExceptModel(destinationFolderPath);

            //// 2. 将 model 文件夹中的内容剪切到路径 A
            //MoveModelContentToRoot(modelFolder, destinationFolderPath);

            //// 3. 删除 model 文件夹
            //Directory.Delete(modelFolder, true);
            DataStore.Instance.sWorkingPath_New = destinationFolderPath;
            return destinationFolderPath;
        }

        static void DeleteExceptModel(string rootPath)
        {
            foreach (var directory in Directory.GetDirectories(rootPath))
            {
                if (Path.GetFileName(directory).Equals("model", StringComparison.OrdinalIgnoreCase))
                    continue;
                if (Path.GetFileName(directory).Equals("replace", StringComparison.OrdinalIgnoreCase))
                    continue;

                Directory.Delete(directory, true);
            }

            foreach (var file in Directory.GetFiles(rootPath))
            {
                File.Delete(file);
            }
        }//工具方法{待定}

        // 将 model 文件夹中的所有内容移动到路径 A
        static void MoveModelContentToRoot(string modelFolder, string rootPath)
        {
            foreach (var file in Directory.GetFiles(modelFolder))
            {
                string destFile = Path.Combine(rootPath, Path.GetFileName(file));
                File.Move(file, destFile);
            }

            foreach (var directory in Directory.GetDirectories(modelFolder))
            {
                string destDir = Path.Combine(rootPath, Path.GetFileName(directory));
                Directory.Move(directory, destDir);
            }
        }//工具方法{待定}

        //将dDictionaryData数据树状结构显示在 TreeView 控件中
        public void ShowTreeView(Dictionary<string, object> dDictionaryData)
        {
            var form = new TreeViewForm();
            form.LoadDictionaryData(dDictionaryData); // 传入字典数据
            form.Show();
        }//工具方法{待定}
        //工具方法
        public List<Dictionary<string, object>> GetTargetModel()
        {
            IModelDoc2 oActiveDoc = GetActiveDocument();
            List<Dictionary<string, object>> lTargetList = new List<Dictionary<string, object>>();
            if (oActiveDoc.GetTitle().EndsWith(".sldprt", StringComparison.OrdinalIgnoreCase))
            {
                Dictionary<string, object> dTarget = new Dictionary<string, object>
                {
                    {"Title",  oActiveDoc.GetTitle()},
                    {"ModelDoc",  oActiveDoc},
                };
                lTargetList.Add(dTarget);
            }
            else
            {
                var dFirstSubObj = DataStore.Instance.TreeViewData["SubComp"];
                var parentChildMap = DataStore.Instance.GetParentChildMap();
                if (dFirstSubObj is Dictionary<string, object> dFirstSubDict2)
                {
                    var dHandleData = DataStore.Instance.ConvertInputData(dFirstSubDict2);
                    foreach (var mainNode in dHandleData)
                    {
                        if (mainNode.Value.ContainsKey("SubComp"))
                        {
                            var subComponents = mainNode.Value["SubComp"] as Dictionary<string, object>;
                            foreach (var subNode in subComponents)
                            {
                                var sElement = subNode.Key;

                                List<string> path = new List<string> { sElement };

                                while (parentChildMap.ContainsKey(sElement))
                                {
                                    sElement = parentChildMap[sElement];
                                    if (sElement != null && sElement != "null")
                                    {
                                        path.Insert(0, sElement);
                                    }
                                }

                                IModelDoc2 targetModelDoc = _commonInterface.GetTargetModelDoc2(path, oActiveDoc);
                                Dictionary<string, object> dTarget = new Dictionary<string, object>
                                {
                                    {"Title",  subNode.Key},
                                    {"ModelDoc",  targetModelDoc},
                                };
                                lTargetList.Add(dTarget);
                            }
                        }
                    }
                }
            }
            return lTargetList;
        }//工具方法（solidworks）

        //该方法目前没有使用
        public void RecordEquationData()
        {
            return;
            IModelDoc2 oActiveDoc = GetActiveDocument();//获取当前文档
            if (oActiveDoc != null)
            {
                List<Dictionary<string, object>> lTargetList = GetTargetModel();
                foreach (var dTarget in lTargetList)
                {
                    Dictionary<string, Dictionary<string, string>> equationsDict
                        = _commonInterface.GetEquationsFromModelDoc2((IModelDoc2)dTarget["ModelDoc"]);
                    if (equationsDict != null && equationsDict.Count != 0)
                    {
                        DataStore.Instance.EquationData[(string)dTarget["Title"]] = equationsDict;
                    }

                }
            }
            else
            {
                MessageBox.Show("当前没有打开的模型文档");
            }
        }//工具方法（solidworks）


        private void RemoveTaskPane()
        {
            if (taskPaneView != null)
            {
                taskPaneView.DeleteView();
                taskPaneView = null;
                taskPaneHost = null;
            }
        }
        #endregion
        #region UI Methods //UI方法
        /// <summary>
        /// 当前dll路径, 最后路径无\
        /// </summary>
        /// <returns></returns>
        public string RegDllPath()
        {
            try
            {
                string codeBase = Assembly.GetExecutingAssembly().CodeBase;
                UriBuilder uri = new UriBuilder(codeBase);
                string path = Uri.UnescapeDataString(uri.Path);
                return Path.GetDirectoryName(path);
            }
            catch (Exception)
            {
                return "";
            }
        } //工具类
        //清除插件添加到 SolidWorks 命令栏的按钮或菜单组。
        public void RemoveCommandMgr()
        {
            iCmdMgr.RemoveCommandGroup(mainCmdGroupID);
            iCmdMgr.RemoveFlyoutGroup(flyoutGroupID);
        }

        //判断两个命令ID列表是否相同

        public bool CompareIDs(int[] storedIDs, int[] addinIDs)
        {
            List<int> storedList = new List<int>(storedIDs);
            List<int> addinList = new List<int>(addinIDs);

            addinList.Sort();
            storedList.Sort();

            if (addinList.Count != storedList.Count)
            {
                return false;
            }
            else
            {

                for (int i = 0; i < addinList.Count; i++)
                {
                    if (addinList[i] != storedList[i])
                    {
                        return false;
                    }
                }
            }
            return true;
        }//工具类{待定}
        //添加一个属性管理器面板
        public Boolean AddPMP()
        {
            ppage = new UserPMPage(this);
            return true;
        }
        //关闭并释放属性面板对象。
        public Boolean RemovePMP()
        {
            ppage = null;
            return true;
        }

        #endregion

        #region UI Callbacks
        public void CreateCube()
        {
            //make sure we have a part open
            string partTemplate = iSwApp.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplatePart);
            if ((partTemplate != null) && (partTemplate != ""))
            {
                IModelDoc2 modDoc = (IModelDoc2)iSwApp.NewDocument(partTemplate, (int)swDwgPaperSizes_e.swDwgPaperA2size, 0.0, 0.0);

                modDoc.InsertSketch2(true);
                modDoc.SketchRectangle(0, 0, 0, .1, .1, .1, false);
                //Extrude the sketch
                IFeatureManager featMan = modDoc.FeatureManager;
                featMan.FeatureExtrusion(true,
                    false, false,
                    (int)swEndConditions_e.swEndCondBlind, (int)swEndConditions_e.swEndCondBlind,
                    0.1, 0.0,
                    false, false,
                    false, false,
                    0.0, 0.0,
                    false, false,
                    false, false,
                    true,
                    false, false);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("There is no part template available. Please check your options and make sure there is a part template selected, or select a new part template.");
            }
        }//工具方法{待定}（solidworks）
        //显示第三方弹出菜单
        public void PopupCallbackFunction()
        {
            bool bRet;

            bRet = iSwApp.ShowThirdPartyPopupMenu(registerID, 500, 500);
        }//工具方法{待定}（solidworks）
        //判断存在活动文档
        public int PopupEnable()
        {
            if (iSwApp.ActiveDoc == null)
                return 0;
            else
                return 1;
        }//工具类{待定}（solidworks）
        //日志
        public void TestCallback()
        {
            Logger.Instance.Log("Test Callback, CSharp");
        }//工具方法{待定}
        //日志

        public int EnableTest()
        {
            if (iSwApp.ActiveDoc == null)
                return 0;
            else
                return 1;
        }//工具方法{待定}（solidworks）

        //显示插件的属性面板界面
        public void ShowPMP()
        {
            if (ppage != null)
                ppage.Show();
        }

        public int EnablePMP()
        {
            if (iSwApp.ActiveDoc != null)
                return 1;
            else
                return 0;
        }//工具方法{待定}（solidworks）
        //更新工具栏中下拉按钮组
        public void FlyoutCallback()
        {
            FlyoutGroup flyGroup = iCmdMgr.GetFlyoutGroup(flyoutGroupID);
            flyGroup.RemoveAllCommandItems();

            flyGroup.AddCommandItem(System.DateTime.Now.ToLongTimeString(), "test", 0, "FlyoutCommandItem1", "FlyoutEnableCommandItem1");

        }
        public int FlyoutEnable()
        {
            return 1;
        }
        //显示"Flyout command 1的消息
        public void FlyoutCommandItem1()
        {
            iSwApp.SendMsgToUser("Flyout command 1");
        }//工具方法{待定}（solidworks）
        public int FlyoutEnableCommandItem1()
        {
            return 1;
        }//工具方法{待定}（solidworks）
        //获取当前活动文档
        public IModelDoc2 GetActiveDocument()//工具方法（solidworks）
        {
            if (iSwApp != null)
            {
                return (IModelDoc2)iSwApp.ActiveDoc;
            }
            return null;
        }
        //通过文件资源管理器窗口选择并打开一个 SolidWorks 模型文件（零件或装配体）
        public IModelDoc2 OpenDocumentFromFileExplorer()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "SolidWorks Files|*.sldprt;*.sldasm|Part Files (*.sldprt)|*.sldprt|Assembly Files (*.sldasm)|*.sldasm",
                InitialDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
            };

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = openFileDialog.FileName;
                return OpenDocument(filePath);
            }
            return null;
        }//工具方法solidworks
        /// <summary>
        /// 打开零级、装配体文档
        /// </summary>
        public IModelDoc2 OpenDocument(string filePath)
        {
            int docType = 0;

            if (filePath.EndsWith(".sldprt", StringComparison.OrdinalIgnoreCase))//是否是零件
            {
                docType = (int)swDocumentTypes_e.swDocPART;
            }
            else if (filePath.EndsWith(".sldasm", StringComparison.OrdinalIgnoreCase))//是否是装配体
            {
                docType = (int)swDocumentTypes_e.swDocASSEMBLY;
            }

            if (iSwApp != null && docType != 0)
            {
                Logger.Instance.Log($"Open Doc Success:{filePath}");
                return (IModelDoc2)iSwApp.OpenDoc6(filePath, docType, (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", 0, 0);
            }
            return null;
        }//工具方法（solidworks）

        /// <summary>
        ///获取当前激活装配体文档中的所有组件信息，并整理成字典返回
        /// </summary>
        public Dictionary<string, object> GetAssemblyComponentsAndMates()
        {
            var result = new Dictionary<string, object>();

            // 获取当前激活的文档
            IModelDoc2 modelDoc = (IModelDoc2)iSwApp.ActiveDoc;
            if (modelDoc == null || !(modelDoc is IAssemblyDoc))
            {
                Logger.Instance.Log("No active assembly document.");
                return result;
            }//判断文档类型是否为装配体文档或者是打开

            AssemblyDoc assemblyDoc = (AssemblyDoc)modelDoc;
            object[] components = (object[])assemblyDoc.GetComponents(false);//获取装配体内所有组件
            var sIterationName2 = GetParentComponentPath(null, modelDoc, true);

            if (components != null)
            {
                // 遍历所有组件
                foreach (Component2 component in components)
                {
                    string componentName = component.Name2;
                    string suppressionState = ((swComponentSuppressionState_e)component.GetSuppression()).ToString();
                    bool bContain = false;

                    if (component.GetParent() != null)
                    {
                        string sParentRoot = string.Concat(component.GetParent().Name2, "/");
                        bContain = component.Name2.Contains(sParentRoot);
                    }
                    if (!bContain)
                    {
                        result[componentName + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                    {
                        {"TypeName",  "MainComps"},
                        {"CompressState",  suppressionState},
                        {"Lenth", "null" },
                        {"Equation",  ""},
                        {"sName",  componentName},
                        {"TempName",  CommonTools.Instance.GetTempName(componentName + Defines.Parent_Split + sIterationName2)},
                        {"Parent",  modelDoc.GetTitle()},
                    }; // 部件没有数值，设置为0
                    }

                }
            }


            // 遍历所有配合关系
            // MateCoincident
            var swModel = (ModelDoc2)assemblyDoc;
            var swFeat = (Feature)swModel.FirstFeature();
            double[] swDimCollect;
            double swDimValue = 0;
            string swMateName;
            string swMateuppressionState;

            Feature swSubFeat;
            DisplayDimension swDisDim;
            Dimension swDim;

            while (swFeat != null)
            {
                if (swFeat.GetTypeName2() == "MateGroup")
                {
                    swSubFeat = (Feature)swFeat.GetFirstSubFeature();
                    while (swSubFeat != null)
                    {
                        Mate2 swMate = (Mate2)swSubFeat.GetSpecificFeature2();
                        if ((swMate != null))
                        {
                            swMateName = swSubFeat.Name;
                            swMateuppressionState = swSubFeat.IsSuppressed().ToString();
                            if (swMate.Type == (int)swMateType_e.swMateANGLE || swMate.Type == (int)swMateType_e.swMateDISTANCE)
                            {
                                swDisDim = swMate.DisplayDimension2[0];
                                swDim = swDisDim.GetDimension2(0);
                                swDimCollect = (double[])swDim.GetValue3((int)swInConfigurationOpts_e.swAllConfiguration, null);
                                swDimValue = swDimCollect[0];

                            }
                            result[swMateName + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                            {
                                {"TypeName",  "Mates"},
                                {"CompressState",  swMateuppressionState},
                                {"Lenth", swDimValue.ToString() },
                                {"Equation",  ""},
                                {"sName",  swMateName},
                                {"TempName",  CommonTools.Instance.GetTempName(swMateName + Defines.Parent_Split + sIterationName2)},
                                {"MateType",  (swMateType_e)swMate.Type},
                                {"Parent",  swModel.GetTitle()},
                            };
                        }
                        swSubFeat = (Feature)swSubFeat.GetNextSubFeature();
                    }
                }
                //else
                //{
                //    Logger.Instance.Log($"Name = {swFeat.Name}, Type = {swFeat.GetTypeName2()}");
                //    if (dRecordFeatureTypes.TryGetValue(swFeat.GetTypeName2(), out var properties))
                //    {
                //        if (!result.ContainsKey(swFeat.Name) && !swFeat.Name.Contains("__EndTag__"))
                //        {
                //            result[swFeat.Name + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                //            {
                //                {"TypeName",  swFeat.GetTypeName2()},
                //                {"CompressState",  swFeat.IsSuppressed().ToString()},
                //                {"Lenth",  "null"},
                //                {"Equation",  ""},
                //                {"sName",  swFeat.Name},
                //                {"TempName",  GetTempName(swFeat.Name + Defines.Parent_Split + sIterationName2)},
                //                {"Parent",  swModel.GetTitle()},
                //            };
                //        }
                //    }
                //}
                //Logger.Instance.Log("run GetAssemblyComponentsAndMates");
                TraverseFeatures(result, swFeat, true, null);
                swFeat = (Feature)swFeat.GetNextFeature();
            }

            

            return new Dictionary<string, object>
                        {
                            { "TypeName", "Component" },
                            { "CompressState", "null" },
                            { "Equation", "null" },
                            { "SubComp", result },
                            { "Parent", "null" },
                            { "sName", "" },
                        };
        }//工具方法solidworks
        //递归提取文档结构信息，并且存储在字典中
        public Dictionary<string, object> ProcessDocument(IModelDoc2 doc, IComponent2 oParentComp, Component2 component = null)
        {
            if (doc == null)
            {
                Logger.Instance.Log("No document to process.");
                return null;
            }
            //获取父组件信息
            string sParentName;
            IModelDoc2 oParentCompDoc;
            if (oParentComp == null)
            {
                oParentCompDoc = GetActiveDocument();
            }
            else
            {
                oParentCompDoc = (IModelDoc2)oParentComp.GetModelDoc2();
            }


            if (oParentCompDoc == null)
            {
                sParentName = "null";
            }
            else
            {
                sParentName = oParentCompDoc.GetTitle();
            }
            //区分处理类型
            switch (doc.GetType())
            {
                case (int)swDocumentTypes_e.swDocPART:
                    if (component == null) //主零件
                    {
                        dSubComponentInfo["sName"] = doc.GetTitle();
                        dSubComponentInfo["TypeName"] = "Main";
                        dSubComponentInfo["CompressState"] = "null";
                        dSubComponentInfo["Equation"] = "null";
                        dSubComponentInfo["Parent"] = "null";

                        TraverseParts(null);

                        var MainPartDict = new Dictionary<string, object> {
                            { doc.GetTitle(), dSubComponentInfo },
                        };

                        var MainPartDictCopy = _commonInterface.DeepCopyDictionary(MainPartDict);

                        dSubComponentInfo["SubComp"].Update(MainPartDictCopy);
                        // DataStore.Instance.sMainAssemName = doc.GetTitle();
                        return new Dictionary<string, object>
                        {
                            { "sName", doc.GetTitle() },
                            { "TypeName", "Main-Main" },
                            { "CompressState", "null" },
                            { "Equation", "null" },
                            { "Parent", "null" },
                            { "SubComp", MainPartDict },
                        };
                    }
                    else
                    {
                        IModelDoc2 TestcomponentDoc = (IModelDoc2)component.GetModelDoc2();

                        //Logger.Instance.Log($"Process Part {component.Name2}, {TestcomponentDoc.GetTitle()}");
                        return CreatePropDict(component, oParentComp);
                    }

                case (int)swDocumentTypes_e.swDocASSEMBLY:
                    if (component == null)
                    {
                        dSubComponentInfo["sName"] = doc.GetTitle();
                        dSubComponentInfo["TypeName"] = "Main";
                        dSubComponentInfo["CompressState"] = "null";
                        dSubComponentInfo["Equation"] = "null";
                        dSubComponentInfo["Parent"] = "null";

                        TraverseAssemblyComponents((IAssemblyDoc)doc, null);

                        var MainAssembDict = new Dictionary<string, object> {
                            { doc.GetTitle(), dSubComponentInfo },
                        };
                        // DataStore.Instance.sMainAssemName = doc.GetTitle();
                        return new Dictionary<string, object>
                        {
                            { "sName", doc.GetTitle() },
                            { "TypeName", "Main-Main" },
                            { "CompressState", "null" },
                            { "Equation", "null" },
                            { "Parent", "null" },
                            { "SubComp", MainAssembDict },
                        };
                    }
                    else //走到这里，说明这个已经是子装配体了
                    {
                        IModelDoc2 TestcomponentDoc = (IModelDoc2)component.GetModelDoc2();
                        Logger.Instance.Log($"Process Assem {component.Name2}, {TestcomponentDoc.GetTitle()}");

                        var componentsDict = new Dictionary<string, object>();
                        componentsDict["TypeName"] = "Component";
                        componentsDict["CompressState"] = component.IsSuppressed().ToString();
                        componentsDict["Equation"] = "";
                        componentsDict["Parent"] = sParentName;
                        componentsDict["sName"] = "";
                        TraverseAssemblyComponents((IAssemblyDoc)doc, component, componentsDict, component);
                        return componentsDict;
                    }
                default:
                    Logger.Instance.Log("Unsupported document type.");
                    return null;
            }
        }
        /// <summary>
        ///获取目标组件的所有信息特征和方程式
        /// </summary>    
        private Dictionary<string, object> GetPartProperties(IComponent2 oParentComp)
        {
            var properties = new Dictionary<string, object>();
            IModelDoc2 modelDoc;
            if (oParentComp == null)
            {
                modelDoc = GetActiveDocument();
            }
            else
            {
                modelDoc = (IModelDoc2)oParentComp.GetModelDoc2();
            }

            // 遍历所有特征
            Feature feature = (Feature)modelDoc.FirstFeature();

            TraverseFeatures(properties, feature, true, oParentComp);

            SaveEquation(properties, oParentComp);

            return properties;
        }//工具方法solidworks
        /// <summary>
        /// 提取组件中的全局变量方程式
        /// </summary>

        public void SaveEquation(Dictionary<string, object> dProperties, IComponent2 oParentComp)
        {
            IModelDoc2 modelDoc;
            if (oParentComp == null)
            {
                modelDoc = GetActiveDocument();
            }
            else
            {
                modelDoc = (IModelDoc2)oParentComp.GetModelDoc2();
            }
            IEquationMgr equationMgr = (IEquationMgr)modelDoc.GetEquationMgr();
            int equationCount = equationMgr.GetCount();
            IModelDoc2 oActiveDoc = GetActiveDocument();
            var sIterationName2 = GetParentComponentPath(oParentComp, oActiveDoc, true);

            for (int i = 0; i < equationCount; i++)
            {
                string equationName = equationMgr.Equation[i];
                bool bGlobalVar = equationMgr.GlobalVariable[i];  // 获取方程式的名称
                string[] equationParts = equationName.Split('=');

                if (equationParts.Length == 2 && bGlobalVar)
                {
                    string name = equationParts[0].Trim().Replace("\"", "");
                    string expression = equationParts[1].Trim().Replace("\"", "");

                    dProperties[name + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                    {
                        {"TypeName",  "Equation"},
                        {"Value",  expression},
                        {"Equation",  ""},
                        {"sName",  name},
                        {"TempName",  CommonTools.Instance.GetTempName(name + Defines.Parent_Split + sIterationName2)},
                        {"Parent",  modelDoc.GetTitle()},
                        {"CompressState",  false.ToString()},
                    };
                }
            }
        }//工具方法solidworks
        /// <summary>
        /// 遍历装配体组件和配合
        /// </summary>
        private void TraverseAssemblyComponents(IAssemblyDoc assemblyDoc, IComponent2 oParentComp, Dictionary<string, object> subComDict = null, Component2 swComp = null)
        {
            var subSubCompDict = new Dictionary<string, object>();
            var CompDict = new Dictionary<string, object>();
            IModelDoc2 oActiveDoc = GetActiveDocument();
            var sIterationName2 = GetParentComponentPath(oParentComp, oActiveDoc, true);

            if (assemblyDoc == null)
            {

            }

            if (swComp != null)
            {
                var swModel = (ModelDoc2)swComp.GetModelDoc2();
                var swFeat = (Feature)swModel.FirstFeature();
                double[] swDimCollect;
                double swDimValue = 0;
                string swMateName;
                string swMateuppressionState;
                Feature swSubFeat;
                DisplayDimension swDisDim;
                Dimension swDim;

                while (swFeat != null)
                {
                    //Logger.Instance.Log($"swFeat.GetTypeName2() == {swFeat.GetTypeName2()}");
                    if (swFeat.GetTypeName2() == "MateGroup")
                    {
                        swSubFeat = (Feature)swFeat.GetFirstSubFeature();
                        while (swSubFeat != null)
                        {
                            Logger.Instance.Log($"swSubFeat.MateType == {swSubFeat.GetTypeName2()}, Name = {swSubFeat.Name}");
                            if(swSubFeat.GetTypeName2() == "MateInPlace")
                            {
                                AddProp(subSubCompDict, swSubFeat, false, oParentComp);
                                swSubFeat = (Feature)swSubFeat.GetNextSubFeature();
                                continue;
                            }
                            Mate2 swMate = (Mate2)swSubFeat.GetSpecificFeature2();
                            if ((swMate != null))
                            {
                                swMateName = swSubFeat.Name;
                                swMateuppressionState = swSubFeat.IsSuppressed().ToString();
                                if (swMate.Type == (int)swMateType_e.swMateANGLE || swMate.Type == (int)swMateType_e.swMateDISTANCE)
                                {
                                    swDisDim = swMate.DisplayDimension2[0];
                                    swDim = swDisDim.GetDimension2(0);
                                    swDimCollect = (double[])swDim.GetValue3((int)swInConfigurationOpts_e.swAllConfiguration, null);
                                    swDimValue = swDimCollect[0];

                                }
                                subSubCompDict[swMateName + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                                    {
                                        {"TypeName",  "Mates"},
                                        {"CompressState",  swMateuppressionState},
                                        {"Lenth", swDimValue.ToString() },
                                        {"sName",  swMateName},
                                        {"TempName",  CommonTools.Instance.GetTempName(swMateName + Defines.Parent_Split + sIterationName2)},
                                        {"Equation",  ""},
                                        {"MateType",  (swMateType_e)swMate.Type},
                                        {"Parent",  swModel.GetTitle()},
                                    };
                            }
                            swSubFeat = (Feature)swSubFeat.GetNextSubFeature();
                        }
                    }
                    else
                    {
                        TraverseFeatures(subSubCompDict, swFeat, false, oParentComp);
                    }
                    swFeat = (Feature)swFeat.GetNextFeature();
                }
            }

            object[] components = (object[])assemblyDoc.GetComponents(false);
            ModelDoc2 oModelDoc = (ModelDoc2)assemblyDoc;

            if (components != null)
            {
                foreach (object comp in components)
                {
                    var component = (Component2)comp;
                    string sParentRoot;
                    bool bContain = false;

                    bool wasSuppressed = component.IsSuppressed();
                    // 如果组件被压缩（抑制）
                    if (wasSuppressed)
                        continue;

                    // 获取 IModelDoc2 对象
                    IModelDoc2 componentDoc = (IModelDoc2)component.GetModelDoc2();
                    string componentDocTitle = componentDoc.GetTitle();

                    if (component.GetParent() != null)
                    {
                        sParentRoot = string.Concat(component.GetParent().Name2, "/");
                        bContain = component.Name2.Contains(sParentRoot);
                    }
                    if (!bContain)
                    {
                        subSubCompDict[component.Name2 + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                        {
                            {"TypeName",  "SubComps"},
                            {"CompressState",  component.IsSuppressed().ToString()},
                            {"Lenth", "null" },
                            {"Equation",  ""},
                            {"sName",  component.Name2},
                            {"Parent",  oModelDoc.GetTitle()},
                            {"TempName",  CommonTools.Instance.GetTempName(component.Name2 + Defines.Parent_Split + sIterationName2)},
                        };

                        CompDict[componentDocTitle] = ProcessDocument(componentDoc, null, component);

                    }
                }
            }

            if (dSubComponentInfo.TryGetValue("SubComp", out var unuseDict))
            {
                dSubComponentInfo["SubComp"].Update(CompDict);
            }
            else
            {
                dSubComponentInfo["SubComp"] = CompDict;
            }

            if (subComDict != null)
            {
                subComDict["SubComp"] = subSubCompDict;
            }
        }

        /// <summary>
        /// 遍历特征
        /// </summary>
        /// <param name="thisFeat"></param>
        /// <param name="isTopLevel"></param>
        public void TraverseFeatures(Dictionary<string, object> dProperties, Feature thisFeat, bool isTopLevel, IComponent2 oParentComp, bool isShowDimension = true)
        {
            Feature curFeat = thisFeat;
            while ((curFeat != null))
            {
                //输出特征名称
                //Logger.Instance.Log("run TraverseFeatures");
                AddProp(dProperties, curFeat, false, oParentComp);
                if (isShowDimension == true) ShowDimensionForFeature(dProperties, curFeat, oParentComp);

                Feature subfeat = (Feature)curFeat.GetFirstSubFeature();
                while ((subfeat != null))
                {
                    TraverseFeatures(dProperties, subfeat, false, oParentComp);
                    subfeat = subfeat.GetNextSubFeature();
                }

                Feature nextFeat;

                if (isTopLevel)
                {
                    nextFeat = (Feature)curFeat.GetNextFeature();
                }
                else
                {
                    nextFeat = null;
                }

                curFeat = nextFeat;
            }

            // 打印结果到控制台
            //Logger.Instance.Log(sb.ToString());
        }//工具方法solidworks
        /// <summary>
        ///收集特征尺寸
        /// </summary>
        public void ShowDimensionForFeature(Dictionary<string, object> dProperties, Feature feature, IComponent2 oParentComp)
        {
            var thisDisplayDim = (DisplayDimension)feature.GetFirstDisplayDimension();

            while (thisDisplayDim != null)
            {
                var dimen = (Dimension)thisDisplayDim.GetDimension();

                AddProp(dProperties, dimen, true, oParentComp);

                thisDisplayDim = (DisplayDimension)feature.GetNextDisplayDimension(thisDisplayDim);
            }
        }//工具方法solidworks
        /// <summary>
        /// 创建特征属性字典
        /// </summary>
        private Dictionary<string, object> CreatePropDict(Component2 oComp, IComponent2 oParentComp)
        {
            var dProperties = new Dictionary<string, object>();
            AddProp(dProperties, oComp, false, oParentComp);
            return dProperties;
        }//工具方法solidworks
        /// <summary>
        /// 添加属性到字典
        /// </summary>
        public void AddProp(Dictionary<string, object> dProperties, object oObject, bool bDimension, IComponent2 oParentComp)
        {
            Dimension oDimension;
            Feature oCurFeat;
            Component2 oComp;
            IModelDoc2 oActiveDoc = GetActiveDocument();
            IModelDoc2 oParentCompDoc;
            if (oParentComp == null)
            {
                oParentCompDoc = oActiveDoc;
            }
            else
            {
                oParentCompDoc = (IModelDoc2)oParentComp.GetModelDoc2();
            }

            string sParentName = oParentCompDoc.GetTitle();

            var sIterationName2 = GetParentComponentPath(oParentComp, oActiveDoc, true);

            if (bDimension == true)
            {
                oDimension = (Dimension)oObject;

                if (!dProperties.ContainsKey(oDimension.GetNameForSelection()))
                {
                    dProperties[oDimension.GetNameForSelection() + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                    {
                        {"TypeName",  "Dimension"},
                        {"Lenth",  oDimension.Value.ToString()},
                        {"Equation",  ""},
                        {"sName",  oDimension.GetNameForSelection()},
                        {"Parent",  sParentName},
                        {"CompressState",  false.ToString()},
                        {"TempName",  CommonTools.Instance.GetTempName(oDimension.GetNameForSelection() + Defines.Parent_Split + sIterationName2)},
                    };
                }
            }
            else
            {
                if (oObject is Component2)
                {
                    oComp = (Component2)oObject;
                    IPartDoc oSubPartDoc = (IPartDoc)oComp.GetModelDoc2();
                    dProperties["TypeName"] = "Component";
                    dProperties["CompressState"] = oComp.IsSuppressed().ToString();
                    dProperties["Equation"] = "";
                    dProperties["Lenth"] = "null";
                    dProperties["Parent"] = sParentName;
                    dProperties["SubComp"] = GetPartProperties(oComp);

                }
                else
                {
                    oCurFeat = (Feature)oObject;
                    //Logger.Instance.Log("run AddProp");
                    if(oCurFeat.Name.Contains("点1"))
                        Logger.Instance.Log($"AddProp - Name = {oCurFeat.Name}, Type = {oCurFeat.GetTypeName2()}");
                    if (dRecordFeatureTypes.TryGetValue(oCurFeat.GetTypeName2(), out var properties))
                    {
                        if (!dProperties.ContainsKey(oCurFeat.Name) && !oCurFeat.Name.Contains("__EndTag__"))
                        {
                            dProperties[oCurFeat.Name + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                            {
                                {"TypeName",  oCurFeat.GetTypeName2()},
                                {"CompressState",  oCurFeat.IsSuppressed().ToString()},
                                {"Lenth",  "null"},
                                {"Equation",  ""},
                                {"sName",  oCurFeat.Name},
                                {"TempName",  CommonTools.Instance.GetTempName(oCurFeat.Name + Defines.Parent_Split + sIterationName2)},
                                {"Parent",  sParentName},
                            };
                        }
                    }
                    else
                    {
                        
                    }

                    // 草图在上面被记录为可压缩对象，下面针对草图，获取里面的方程式曲线
                    if (oCurFeat.GetTypeName2() == "ProfileFeature" || oCurFeat.GetTypeName2() == "Sketch")
                    {
                        Sketch sketch = oCurFeat.GetSpecificFeature2() as Sketch;
                        if (sketch != null)
                        {
                            // 成功获取 Sketch 对象！
                            //Logger.Instance.Log("✅ 成功将 Feature 转换为 Sketch！");
                            List<SketchSpline> SplineList = CommonTools.GetEquationCurvesFromSketch(sketch);
                            foreach (SketchSpline SpLine in SplineList)
                            {
                                dProperties[(SpLine as SketchSegment).GetName() + Defines.Parent_Split + sIterationName2] = new Dictionary<string, object>
                                    {
                                        {"TypeName",  "SketchSpline"},
                                        {"CompressState",  oCurFeat.IsSuppressed().ToString()},
                                        {"Lenth",  "null"},
                                        {"Equation",  ""},
                                        {"sName",  (SpLine as SketchSegment).GetName()},
                                        {"TempName",  CommonTools.Instance.GetTempName((SpLine as SketchSegment).GetName() + Defines.Parent_Split + sIterationName2)},
                                        {"Parent",  sParentName},
                                    };
                            }
                        }
                        else
                        {
                            Logger.Instance.Log("❌ 转换失败，GetSpecificFeature2() 不是 Sketch");
                        }
                    }
                }
            }
        }//工具方法solidworks
        /// <summary>
        /// 遍历装配体的组件
        /// </summary>
        public void TraverseParts(IComponent2 oParentComp)
        {
            var PartDict = new Dictionary<string, object>();
            PartDict = GetPartProperties(oParentComp);
            if (dSubComponentInfo.TryGetValue("SubComp", out var unuseDict))
            {
                dSubComponentInfo["SubComp"].Update(PartDict);
            }
            else
            {
                dSubComponentInfo["SubComp"] = PartDict;
            }
        }

        #endregion

        #region Event Methods //事件方法
        /// <summary>
        /// 提取草图中的方程式曲线
        /// </summary>
        public bool AttachEventHandlers()
        {
            AttachSwEvents();
            //Listen for events on all currently open docs
            AttachEventsToAllDocuments();
            return true;
        }
        /// <summary>
        /// 挂接 SolidWorks 应用级事件
        /// </summary>
        
        private bool AttachSwEvents()
        {
            try
            {
                SwEventPtr.ActiveDocChangeNotify += new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(CommonTools.Instance.OnDocChange);
                SwEventPtr.DocumentLoadNotify2 += new DSldWorksEvents_DocumentLoadNotify2EventHandler(CommonTools.Instance.OnDocLoad);
                SwEventPtr.FileNewNotify2 += new DSldWorksEvents_FileNewNotify2EventHandler(OnFileNew);
                SwEventPtr.ActiveModelDocChangeNotify += new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(CommonTools.Instance.OnModelChange);
                SwEventPtr.FileOpenPostNotify += new DSldWorksEvents_FileOpenPostNotifyEventHandler(FileOpenPostNotify);
                return true;
            }
            catch (Exception e)
            {
                Debug.Print(e.Message);
                return false;
            }
        }
        /// 移除  SolidWorks 应用级事件
        /// </summary>
        private bool DetachSwEvents()
        {
            try
            {
                SwEventPtr.ActiveDocChangeNotify -= new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(CommonTools.Instance.OnDocChange);
                SwEventPtr.DocumentLoadNotify2 -= new DSldWorksEvents_DocumentLoadNotify2EventHandler(CommonTools.Instance.OnDocLoad);
                SwEventPtr.FileNewNotify2 -= new DSldWorksEvents_FileNewNotify2EventHandler(OnFileNew);
                SwEventPtr.ActiveModelDocChangeNotify -= new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(CommonTools.Instance.OnModelChange);
                SwEventPtr.FileOpenPostNotify -= new DSldWorksEvents_FileOpenPostNotifyEventHandler(FileOpenPostNotify);
                return true;
            }
            catch (Exception e)
            {
                Debug.Print(e.Message);
                return false;
            }

        }
        /// </summary>
        /// 给当前所有已打开文档添加事件处理器
        /// </summary>
        public void AttachEventsToAllDocuments()
        {
            ModelDoc2 modDoc = (ModelDoc2)iSwApp.GetFirstDocument();
            while (modDoc != null)
            {
                if (!openDocs.Contains(modDoc))
                {
                    AttachModelDocEventHandler(modDoc);
                }
                else if (openDocs.Contains(modDoc))
                {
                    bool connected = false;
                    DocumentEventHandler docHandler = (DocumentEventHandler)openDocs[modDoc];
                    if (docHandler != null)
                    {
                        connected = docHandler.ConnectModelViews();
                    }
                }

                modDoc = (ModelDoc2)modDoc.GetNext();
            }
        }
        /// </summary>
        /// 为指定文档对象绑定事件处理器
        /// </summary>
        public bool AttachModelDocEventHandler(ModelDoc2 modDoc)
        {
            if (modDoc == null)
                return false;

            DocumentEventHandler docHandler = null;

            if (!openDocs.Contains(modDoc))
            {
                switch (modDoc.GetType())
                {
                    case (int)swDocumentTypes_e.swDocPART:
                        {
                            docHandler = new PartEventHandler(modDoc, this);
                            break;
                        }
                    case (int)swDocumentTypes_e.swDocASSEMBLY:
                        {
                            docHandler = new AssemblyEventHandler(modDoc, this);
                            break;
                        }
                    case (int)swDocumentTypes_e.swDocDRAWING:
                        {
                            docHandler = new DrawingEventHandler(modDoc, this);
                            break;
                        }
                    default:
                        {
                            return false; //Unsupported document type
                        }
                }
                docHandler.AttachEventHandlers();
                openDocs.Add(modDoc, docHandler);
            }
            return true;
        }
        /// </summary>
        /// 为指定文档对象移除事件处理器
        /// </summary>
        public bool DetachModelEventHandler(ModelDoc2 modDoc)
        {
            DocumentEventHandler docHandler;
            docHandler = (DocumentEventHandler)openDocs[modDoc];
            openDocs.Remove(modDoc);
            modDoc = null;
            docHandler = null;
            return true;
        }
        /// </summary>
        /// 卸载所有事件
        /// </summary>
        public bool DetachEventHandlers()
        {
            DetachSwEvents();

            //Close events on all currently open docs
            DocumentEventHandler docHandler;
            int numKeys = openDocs.Count;
            object[] keys = new Object[numKeys];

            //Remove all document event handlers
            openDocs.Keys.CopyTo(keys, 0);
            foreach (ModelDoc2 key in keys)
            {
                docHandler = (DocumentEventHandler)openDocs[key];
                docHandler.DetachEventHandlers(); //This also removes the pair from the hash
                docHandler = null;
            }
            return true;
        }
        #endregion
      
        #region Event Handlers  //事件处理程序
        /// </summary>
        ///文件打开后通知
        /// </summary>
        int FileOpenPostNotify(string FileName)
        {
            AttachEventsToAllDocuments();
            return 0;
        }
        /// </summary>
        ///新建文件事件
        /// </summary>
        public int OnFileNew(object newDoc, int docType, string templateName)
        {
            AttachEventsToAllDocuments();
            return 0;
        }
        #endregion

        #region 驱动
        /// <summary>
        /// 根据配置文件（规则配置）驱动模型中的尺寸、压缩、替换、方程式曲线等元素，来实现模型的自动化修改与工程图生成。/// 
        /// </summary>
        public void DoDriveModel()
        {
            var dAllRuleConfigData = dlgRuleConfig.RuleConfigModel.Instance.GetAllRuleConfigData();
            // 初始化记录要处理的各种规则项
            DimDict = new Dictionary<string, string>();
            DimEquDict = new Dictionary<string, string>();
            SupDict = new Dictionary<string, string>();
            SupEquDict = new Dictionary<string, string>();
            RepDict = new Dictionary<string, string>();
            SpLineDict = new Dictionary<string, string>();

            CacheDimValue = new Dictionary<string, double>();
            CacheSupState = new Dictionary<string, bool>();
            //分析所有规则配置项
            foreach (var Mainkvp in dAllRuleConfigData)
            {
                string sFullPath = Mainkvp.Key;
                string sObjectType = (string)Mainkvp.Value["DriveType"];

                if (Mainkvp.Value["Rule"] is Dictionary<string, object> RuleDict1)
                {
                    if (RuleDict1.ContainsKey("尺寸"))
                    {
                        if (sObjectType == "方程式常量")
                        {
                            DimEquDict[sFullPath] = "undone";
                        }
                        else
                        {
                            DimDict[sFullPath] = "undone";
                        }

                    }
                    if (RuleDict1.ContainsKey("压缩"))
                    {
                        if (sObjectType == "方程式常量")
                        {
                            SupEquDict[sFullPath] = "undone";
                        }
                        else
                        {
                            SupDict[sFullPath] = "undone";
                        }

                    }
                    if (RuleDict1.ContainsKey("替换"))
                    {
                        RepDict[sFullPath] = "undone";
                    }
                    if (RuleDict1.ContainsKey("方程式曲线"))
                    {
                        SpLineDict[sFullPath] = "undone";
                    }
                }
                else if (Mainkvp.Value["Rule"] is Dictionary<string, Dictionary<string, object>> RuleDict2)
                {
                    if (RuleDict2.ContainsKey("尺寸"))
                    {
                        if (sObjectType == "方程式常量")
                        {
                            DimEquDict[sFullPath] = "undone";
                        }
                        else
                        {
                            DimDict[sFullPath] = "undone";
                        }

                    }
                    if (RuleDict2.ContainsKey("压缩"))
                    {
                        if (sObjectType == "方程式常量")
                        {
                            SupEquDict[sFullPath] = "undone";
                        }
                        else
                        {
                            SupDict[sFullPath] = "undone";
                        }

                    }
                    if (RuleDict2.ContainsKey("替换"))
                    {
                        RepDict[sFullPath] = "undone";
                    }
                    if (RuleDict2.ContainsKey("方程式曲线"))
                    {
                        SpLineDict[sFullPath] = "undone";
                    }
                }
            }

            //这里要先更新一遍方程式

            // 思路是每次循环，必处理掉这个元素；如果处理不掉就是异常的。即循环结束后，还有undone的内容，就是异常
            // 如果处理不掉（如涉及到的零部件被压缩导致元素找不到），就跳过
            var SubKeys = SupDict.Keys.ToList();
            var SubEquKeys = SupEquDict.Keys.ToList();
            var DimKeys = DimDict.Keys.ToList();
            var DimEquKeys = DimEquDict.Keys.ToList();
            var RepKeys = RepDict.Keys.ToList();
            var SpLineKeys = SpLineDict.Keys.ToList();
            ModelDoc2 ActiveDoc = iSwApp.ActiveDoc;
            //先把方程式常量计算完
            foreach (var SupDictkvpKey in SubEquKeys)
            {
                try
                {
                    DriveObj(SupDictkvpKey, SupEquDict, "压缩");
                }catch(Exception ex)
                {
                    Logger.Instance.Log($"驱动压缩方程式失败：{ex.Message}");
                    continue;
                }

            }

            foreach (var DimDictkvpKey in DimEquKeys)
            {
                try
                {
                    DriveObj(DimDictkvpKey, DimEquDict, "尺寸");
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log($"驱动尺寸方程式失败：{ex.Message}");
                    continue;
                }
            }

            try
            {
                EvaluateAllEquation(); //驱动所有的方程式
            }
            catch(Exception ex) 
            {
                Logger.Instance.Log($"驱动方程式失败：{ex.Message}");
            }
            
            foreach (var SupDictkvpKey in SubKeys)
            {
                try
                {
                    ActiveDoc.Save();
                    DriveObj(SupDictkvpKey, SupDict, "压缩");
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log($"驱动压缩公式 {SupDictkvpKey} 失败：{ex.Message}");
                    continue;
                }
            }
            foreach (var DimDictkvpKey in DimKeys)
            {
                try
                {
                    ActiveDoc.Save();
                    DriveObj(DimDictkvpKey, DimDict, "尺寸");
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log($"驱动尺寸公式 {DimDictkvpKey} 失败：{ex.Message}");
                    continue;
                }
            }
            foreach (var RepDictkvpKey in RepKeys)
            {
                try
                {
                    ActiveDoc.Save();
                    DriveObj(RepDictkvpKey, RepDict, "替换");
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log($"驱动替换公式 {RepDictkvpKey} 失败：{ex.Message}");
                    continue;
                }
            }
            foreach (var SpLineDictkvpKey in SpLineKeys)
            {
                try
                {
                    ActiveDoc.Save();
                    DriveObj(SpLineDictkvpKey, SpLineDict, "方程式曲线");
                }
                catch (Exception ex)
                {
                    Logger.Instance.Log($"驱动方程式曲线公式 {SpLineDictkvpKey} 失败：{ex.Message}");
                    continue;
                }
                
            }

            ActiveDoc.ForceRebuild3(false);

            // 获取单例对象
            DrawingManager manager = DrawingManager.GetInstance(iSwApp);

            // 获取所有待打开的工程图文件路径
            List<string> drawingFiles = RuleConfigModel.Instance.GetSelectDrwList();

            // 按顺序打开工程图
            manager.OpenDrawingsInOrder(drawingFiles);
            CopyWorkingPathAfterDrive();
        }
        /// </summary>
        ///计算所有目标模型中的方程式
        /// </summary>
        public void EvaluateAllEquation()
        {
            IModelDoc2 oActiveDoc = GetActiveDocument();
            if (oActiveDoc != null)
            {
                List<Dictionary<string, object>> lTargetList = GetTargetModel();
                foreach (var dTarget in lTargetList)
                {
                    IModelDoc2 targetModelDoc = (IModelDoc2)dTarget["ModelDoc"];
                    if(targetModelDoc != null) 
                    {
                        IEquationMgr equationMgr = (IEquationMgr)targetModelDoc.GetEquationMgr();

                        // 计算并更新所有方程式
                        equationMgr.EvaluateAll();

                        // 更新模型以应用方程式的计算结果
                        targetModelDoc.EditRebuild3();
                    }
                    else
                    {
                        continue;
                    }
                    
                }
            }
            else
            {
                MessageBox.Show("当前没有打开的模型文档");
            }
        }//工具方法（solidworks）
        /// </summary>
        ///从装配层级中获取指定对象
        /// </summary>
        public Dictionary<object, string> GetObjectFromAssemblyByHierarchy(List<string> hierarchy, string objectType)
        {
            if (hierarchy == null || hierarchy.Count < 2)
                throw new ArgumentException("GetObjectFromAssemblyByHierarchy - 传入的hierarchy数量至少为2.");

            IModelDoc2 activeDoc = (IModelDoc2)iSwApp.ActiveDoc;

            // 检查第一个元素是否与当前打开的文档名称一致
            if (!activeDoc.GetTitle().Equals(hierarchy[0], StringComparison.OrdinalIgnoreCase))
                throw new Exception("The first element of the hierarchy does not match the active document.");

            IComponent2 currentComponent = null;

            // 从第二个元素开始遍历
            for (int i = 1; i < hierarchy.Count; i++)
            {
                string elementName = hierarchy[i];

                if (i == hierarchy.Count - 1)
                {
                    // 如果是最后一个元素，处理类型并返回对应的对象
                    return GetFinalObject(currentComponent, elementName, objectType, activeDoc);
                }
                else
                {
                    // 获取当前部件中的子部件
                    if (currentComponent == null)
                    {
                        // 在顶层装配体中查找部件
                        currentComponent = FindImmediateComponentByFileName((IAssemblyDoc)activeDoc, elementName);
                    }
                    else
                    {
                        // 在当前部件的直接子部件中查找
                        currentComponent = FindImmediateChildComponent(currentComponent, elementName);
                    }

                    if (currentComponent == null)
                        throw new Exception($"Component {elementName} not found.");
                }
            }

            throw new Exception("Failed to resolve the object.");
        }//工具方法（solidwork）
        /// </summary>
        ///获取指定类型对象
        /// </summary>
        private Dictionary<object, string> GetFinalObject(IComponent2 parentComponent, string elementName, string objectType, IModelDoc2 oModelDoc)
        {
            string MATEsimpleName = elementName.Split(new string[] { Defines.Parent_Split }, StringSplitOptions.None)[0];
            string simpleName = MATEsimpleName.Split(new string[] { Defines.UseValue_Split }, StringSplitOptions.None)[0];
            simpleName = GetReplaceCompName(simpleName);
            Dictionary<object, string> FinalObjectDict = new Dictionary<object, string>();
            if (objectType == null)
            {
                return GetFinalObjectWithoutType(parentComponent, simpleName, oModelDoc);
            }
            switch (objectType.ToLower())
            {
                case "尺寸驱动":
                    ModelDoc2 SwPartDoc;
                    if (parentComponent != null)
                    {
                        int SuppState = parentComponent.GetSuppression2();
                        if (SuppState != (int)swComponentSuppressionState_e.swComponentFullyResolved)
                            parentComponent.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyResolved);

                        SwPartDoc = (ModelDoc2)parentComponent?.GetModelDoc2();

                        parentComponent.SetSuppression2(SuppState);
                    }
                    else
                    {
                        SwPartDoc = (ModelDoc2)oModelDoc;
                    }
                    Dimension oDim = (Dimension)SwPartDoc.Parameter(simpleName);
                    FinalObjectDict[oDim] = objectType;
                    return FinalObjectDict;
                case "特征压缩":
                    if (parentComponent != null)
                    {
                        var oFea = parentComponent?.FeatureByName(simpleName);
                        FinalObjectDict[oFea] = objectType;
                        return FinalObjectDict;

                    }
                    else if (oModelDoc.GetType() == 2)
                    {
                        AssemblyDoc SwAssemDoc2 = (AssemblyDoc)oModelDoc;
                        var oFea = SwAssemDoc2?.FeatureByName(simpleName);
                        FinalObjectDict[oFea] = objectType;
                        return FinalObjectDict;
                    }
                    else
                    {
                        PartDoc SwPartDoc2 = (PartDoc)oModelDoc;
                        var oFea = SwPartDoc2?.FeatureByName(simpleName);
                        FinalObjectDict[oFea] = objectType;
                        return FinalObjectDict;
                    }
                case "配合驱动":
                    IMate2 oMate = null;
                    if (parentComponent == null)
                    {
                        // 从装配体中查找
                        IAssemblyDoc oAssemDoc = (IAssemblyDoc)oModelDoc;
                        oMate = (oAssemDoc?.FeatureByName(simpleName) as IFeature)?.GetSpecificFeature2() as IMate2;

                    }
                    else
                    {
                        // 从父部件的子部件中查找
                        oMate = parentComponent?.FeatureByName(simpleName)?.GetSpecificFeature2() as IMate2;
                    }
                    FinalObjectDict[oMate] = objectType;
                    return FinalObjectDict;
                case "零部件":
                    IComponent2 oComp = null;
                    if (parentComponent == null)
                    {
                        // 从装配体中查找
                        IAssemblyDoc oAssemDoc = (IAssemblyDoc)oModelDoc;
                        oComp = FindComponentInAssembly(oAssemDoc, simpleName);
                    }
                    else
                    {
                        // 从父部件的子部件中查找
                        oComp = FindComponentInParentComponent(parentComponent, simpleName);
                    }
                    FinalObjectDict[oComp] = objectType;
                    return FinalObjectDict;
                case "方程式常量":
                    FinalObjectDict[elementName] = objectType;
                    return FinalObjectDict;
                case "方程式曲线":
                    ModelDoc2 SwDoc;
                    if (parentComponent != null)
                    {
                        SwDoc = (ModelDoc2)parentComponent?.GetModelDoc2();
                    }
                    else
                    {
                        SwDoc = (ModelDoc2)oModelDoc;
                    }

                    SketchSegment SpLine = CommonTools.FindSketchSegmentByName(SwDoc, simpleName);
                    FinalObjectDict[SpLine] = objectType;
                    return FinalObjectDict;

                default:
                    return GetFinalObjectWithoutType(parentComponent, simpleName, oModelDoc);
            }
        }//工具方法（solidwork）
        /// </summary>
        ///推测类型获取对象
        /// </summary>
        private Dictionary<object, string> GetFinalObjectWithoutType(IComponent2 parentComponent, string simpleName, IModelDoc2 oModelDoc)
        {
            Dictionary<object, string> FinalObjectDict = new Dictionary<object, string>();
            IMate2 mate = null;
            if (parentComponent == null)
            {
                if (oModelDoc.GetType() == 2)
                {
                    // 从装配体中查找
                    IAssemblyDoc oAssemDoc = (IAssemblyDoc)oModelDoc;
                    mate = (oAssemDoc?.FeatureByName(simpleName) as IFeature)?.GetSpecificFeature2() as IMate2;

                }
            }
            else
            {
                // 从父部件的子部件中查找
                mate = parentComponent?.FeatureByName(simpleName)?.GetSpecificFeature2() as IMate2;
            }

            if (mate != null)
            {
                FinalObjectDict[mate] = "配合驱动";
                return FinalObjectDict;
            }
            else
            {
                IComponent2 oComp = null;
                if (parentComponent == null)
                {
                    if (oModelDoc.GetType() == 2)
                    {
                        // 从装配体中查找
                        IAssemblyDoc oAssemDoc = (IAssemblyDoc)oModelDoc;
                        oComp = FindComponentInAssembly(oAssemDoc, simpleName);
                    }

                }
                else
                {
                    // 从父部件的子部件中查找
                    oComp = FindComponentInParentComponent(parentComponent, simpleName);
                }

                if (oComp != null)
                {
                    FinalObjectDict[oComp] = "零部件";
                    return FinalObjectDict;
                }
                else
                {
                    Feature feature = null;
                    if (parentComponent != null)
                    {
                        if (oModelDoc.GetType() == 1)
                        {
                            feature = parentComponent?.FeatureByName(simpleName);
                        }
                    }
                    else
                    {
                        if (oModelDoc.GetType() == 2)
                        {
                            AssemblyDoc SwAssemDoc2 = (AssemblyDoc)oModelDoc;
                            feature = (Feature)(SwAssemDoc2?.FeatureByName(simpleName));
                        }
                        else
                        {
                            PartDoc SwPartDoc2 = (PartDoc)oModelDoc;
                            feature = (Feature)(SwPartDoc2?.FeatureByName(simpleName));
                        } 
                    }


                    if (feature != null)
                    {
                        FinalObjectDict[feature] = "特征压缩";
                        return FinalObjectDict;
                    }
                    else
                    {
                        Dimension dimension = null;
                        if (parentComponent != null)
                        {
                            try
                            {
                                
                                ModelDoc2 SwPartDoc = (ModelDoc2)parentComponent?.GetModelDoc2();
                                dimension = (Dimension)SwPartDoc.Parameter(simpleName);
                            }catch(Exception ex)
                            {
                                Logger.Instance.Log($"获取尺寸{simpleName}失败");
                                Logger.Instance.Log($"错误信息：{ex.Message}");
                            }
                        }
                        else
                        {
                            ModelDoc2 SwPartDoc = (ModelDoc2)oModelDoc;
                            dimension = (Dimension)SwPartDoc.Parameter(simpleName);
                        }
                        if (dimension != null)
                        {
                            FinalObjectDict[dimension] = "尺寸驱动";
                            return FinalObjectDict;
                        }
                        else
                        {
                            //
                            ModelDoc2 SwPartDoc;
                            string sFindEquName = null;
                            if (parentComponent != null && oModelDoc.GetType() == 1)
                            {
                                if (oModelDoc.GetType() == 1)
                                {
                                    SwPartDoc = (ModelDoc2)parentComponent?.GetModelDoc2();
                                }
                                else
                                {
                                    Logger.Instance.Log($"找不到方程式对象{simpleName}");
                                    //MessageBox.Show($"找不到方程式对象{simpleName}");
                                    return null;
                                }
                            }
                            else
                            {
                                SwPartDoc = (ModelDoc2)oModelDoc;
                            }
                            Dictionary<string, Dictionary<string, string>> equations = _commonInterface.GetEquationsFromModelDoc2(SwPartDoc);
                            foreach (var oKvp in equations)
                            {
                                string sEquName = oKvp.Key;
                                if (sEquName.Contains(simpleName))
                                {
                                    sFindEquName = sEquName;
                                    break;
                                }

                            }
                            if (!string.IsNullOrEmpty(sFindEquName))
                            {
                                FinalObjectDict[sFindEquName] = "方程式常量";
                                return FinalObjectDict;
                            }
                            else
                            {
                                Logger.Instance.Log($"找不到对象{simpleName}");
                                //MessageBox.Show($"找不到对象{simpleName}");
                                return null;
                            }


                        }
                    }
                }
            }
        }//工具方法（solidwork）
        /// </summary>
        ///根据
        ///文件名查找子部件
        /// </summary>
        private IComponent2 FindImmediateComponentByFileName(IAssemblyDoc assemblyDoc, string componentName)
        {
            object[] components = (object[])assemblyDoc.GetComponents(false);
            if (components == null) return null;

            foreach (var compObj in components)
            {
                IComponent2 comp = compObj as IComponent2;
                if (comp != null && comp.GetPathName().Contains(componentName))
                {
                    return comp;
                }
            }
            return null;
        }//工具方法?
        /// </summary>
        /// </summary>
        ///装备体中按照名称查找部件
        /// </summary>
        private IComponent2 FindComponentInAssembly(IAssemblyDoc assemblyDoc, string componentName)
        {
            object[] components = (object[])assemblyDoc.GetComponents(false);
            if (components == null) return null;

            foreach (var compObj in components)
            {
                IComponent2 comp = compObj as IComponent2;
                if (comp != null && comp.Name2.Equals(componentName, StringComparison.OrdinalIgnoreCase))
                {
                    return comp;
                }
            }
            return null;
        }//工具方法
        /// </summary>
        ///在部件中查找子部件
        /// </summary>
        private IComponent2 FindComponentInParentComponent(IComponent2 parentComponent, string componentName)
        {
            object[] children = (object[])parentComponent.GetChildren();
            if (children == null) return null;

            foreach (var childObj in children)
            {
                IComponent2 child = childObj as IComponent2;
                if (child != null && child.Name2.Contains(componentName))
                {
                    return child;
                }
            }
            return null;
        }//工具方法
        /// </summary>
        ///查找给定组件的一级子组件
        /// </summary>
        private IComponent2 FindImmediateChildComponent(IComponent2 parentComponent, string componentName)
        {
            object[] children = (object[])parentComponent.GetChildren();
            if (children == null) return null;

            foreach (var childObj in children)
            {
                IComponent2 child = childObj as IComponent2;
                if (child != null && child.GetPathName().Contains(componentName))
                {
                    return child;
                }
            }
            return null;
        }//工具方法
        /// </summary>
        ///按规则驱动模型对象属性
        /// </summary>
        public void DriveObj(string sFullPath, Dictionary<string, string> inputDict, string DealKey)
        {
            Logger.Instance.Log($"DriveObj========================{sFullPath}========================{DealKey}");
            if (inputDict[sFullPath] == "done")
            {
                Logger.Instance.Log($"{sFullPath}已被处理");
                return;
            }

            if (DealKey == "压缩")
            {
                if (!HandleSupList.Contains(sFullPath))
                {
                    HandleSupList.Add(sFullPath);//加入处理中列表
                }
                else
                {
                    Logger.Instance.Log($"元素{sFullPath}异常，无法被正常驱动，请检查规则");
                    return;
                }

            }
            else if (DealKey == "尺寸")
            {
                if (!HandleDimList.Contains(sFullPath))
                {
                    HandleDimList.Add(sFullPath);//加入处理中列表
                }
                else
                {
                    Logger.Instance.Log($"元素{sFullPath}异常，无法被正常驱动，请检查规则");
                    HandleDimList.Remove(sFullPath);//移除处理中列表
                    return;
                }
            }
            else if (DealKey == "替换")
            {
                if (!HandleRepList.Contains(sFullPath))
                {
                    HandleRepList.Add(sFullPath);//加入处理中列表
                }
                else
                {
                    Logger.Instance.Log($"元素{sFullPath}异常，无法被正常驱动，请检查规则");
                    HandleRepList.Remove(sFullPath);//移除处理中列表
                    return;
                }
            }


            var dAllRuleConfigData = RuleConfigModel.Instance.GetAllRuleConfigData();
            var RuleDictObj = new Dictionary<string, object>();
            // 直接通过当前模型创建，和读取已有项目。加载出来的RuleDictObj类型不同
            try
            {
                RuleDictObj = (Dictionary<string, object>)dAllRuleConfigData[sFullPath]["Rule"];
            }
            catch (Exception ex)
            {
                RuleDictObj = DictionaryConverter.ConvertToNestedObjectDict((Dictionary<string, Dictionary<string, object>>)dAllRuleConfigData[sFullPath]["Rule"]); ;
            }

            string objectType = (string)dAllRuleConfigData[sFullPath]["DriveType"];
            List<string> lFullPath = CommonTools.Instance.SplitStringByCustomSeparator(sFullPath, Defines.Comp_Split);

            if (RuleDictObj is Dictionary<string, object> RuleDict)
            {
                var dSupRuleObj = RuleDict[DealKey];
                if (dSupRuleObj is Dictionary<string, object> dSupRule)
                {
                    var lFormulaListObj = new List<object>();
                    // 直接通过当前模型创建，和读取已有项目。加载出来的lFormulaListObj类型不同
                    try
                    {
                        List<Dictionary<string, object>> dictList = (List<Dictionary<string, object>>)dSupRule["lFormulaList"];
                        lFormulaListObj = dictList.Cast<object>().ToList();
                    }
                    catch
                    {
                        lFormulaListObj = (List<object>)dSupRule["lFormulaList"];
                    }

                    string sExecFormula = "";
                    string sExecResult = "";

                    // 解析公式里的每一个元素
                    if (lFormulaListObj is List<object> lFormulaList)
                    {
                        foreach (var dFormulaDictObj in lFormulaList)
                        {
                            if (dFormulaDictObj is Dictionary<string, object> dFormulaDict)
                            {
                                string sType = (string)dFormulaDict["Type"];
                                string sValue = (string)dFormulaDict["Value"];

                                if (sType == Defines.Type_Element)
                                {
                                    var sFormulaFullPathObj = dFormulaDict["FullPath"];
                                    if (sFormulaFullPathObj is string sFormulaFullPath)
                                    {
                                        string sSimpleFullPath = sFormulaFullPath.Split(new string[] { Defines.UseValue_Split }, StringSplitOptions.None)[0];
                                        string sUseType = sFormulaFullPath.Split(new string[] { Defines.UseValue_Split }, StringSplitOptions.None)[1];
                                        if (DataStore.Instance.dNote_NameData.ContainsKey(sSimpleFullPath))
                                        {
                                            var sSinglePath = (string)DataStore.Instance.dNote_NameData[sSimpleFullPath];
                                            sSimpleFullPath = CommonTools.Instance.GetFullPath(sSinglePath);
                                        }
                                            
                                        if (sUseType == "DIM")
                                        {
                                            if (DimDict.ContainsKey(sSimpleFullPath))
                                            {
                                                if (DimDict[sSimpleFullPath] == "done")
                                                {
                                                    Logger.Instance.Log($"DIM使用到已处理的属性{sSimpleFullPath}");
                                                    CacheUseProp(sSimpleFullPath, sUseType);
                                                }
                                                else
                                                {
                                                    DriveObj(sSimpleFullPath, DimDict, "尺寸");
                                                }
                                            }
                                            else
                                            {
                                                Logger.Instance.Log($"DIM使用到不需要修改的的属性{sSimpleFullPath}");
                                                CacheUseProp(sSimpleFullPath, sUseType);
                                            }

                                            string sDimValue = CacheDimValue[sSimpleFullPath].ToString();
                                            sExecFormula += sDimValue;
                                        }
                                        else if (sUseType == "SUP")
                                        {
                                            if (SupDict.ContainsKey(sSimpleFullPath))
                                            {
                                                if (SupDict[sSimpleFullPath] == "done")
                                                {
                                                    Logger.Instance.Log($"SUP使用到已处理的属性{sSimpleFullPath}");
                                                    CacheUseProp(sSimpleFullPath, sUseType);
                                                }
                                                else
                                                {
                                                    DriveObj(sSimpleFullPath, SupDict, "压缩");
                                                }
                                            }
                                            else
                                            {
                                                Logger.Instance.Log($"SUP使用到不需要修改的的属性{sSimpleFullPath}");
                                                CacheUseProp(sSimpleFullPath, sUseType);
                                            }

                                            string sSupState = CacheSupState[sSimpleFullPath].ToString();
                                            sExecFormula += sSupState;
                                        }
                                    }
                                    else
                                    {
                                        Logger.Instance.Log($"{sFullPath}规则用到参数{sFormulaFullPathObj}异常");
                                        break;
                                    }

                                }
                                else if (sType == Defines.Type_Arg)
                                {
                                    if (!DataStore.Instance.UIGridData.ContainsKey(sValue))
                                    {
                                        Logger.Instance.Log($"参数{sValue}并没有被成功设置，请检查");
                                        break;
                                    }

                                    string sArgValue = DataStore.Instance.UIGridData[sValue].ToString();
                                    sExecFormula += sArgValue;
                                }
                                else if (sType == Defines.Type_RepFilePath)
                                {
                                    string sFullValue = Path.Combine(DataStore.Instance.sWorkingPath_New, sValue);
                                    sExecFormula += sFullValue;
                                }
                                else if (sType == Defines.Type_SpLine)
                                {
                                    sExecFormula += sValue;
                                }
                                else
                                {
                                    sExecFormula += sValue;
                                }
                            }
                        }
                    }

                    // 根据规则公式计算出值
                    if (DealKey == "方程式曲线")
                    {
                        try
                        {
                            sExecResult = CommonTools.EvaluateConditionExpressions_SPLine(sExecFormula);
                        }
                        catch (Exception ex)
                        {
                            Logger.Instance.Log($"{DealKey}根据表达式{sExecFormula}计算结果失败: {ex.Message}");
                        }
                    }
                    else
                    {
                        try
                        {
                            sExecResult = CommonTools.EvaluateConditionExpressions(sExecFormula);
                        }
                        catch (Exception ex)
                        {
                            Logger.Instance.Log($"{DealKey}根据表达式{sExecFormula}计算结果失败: {ex.Message}");
                        }
                    }


                    Logger.Instance.Log($"解析后的{DealKey}表达式：{sExecFormula}，值为{sExecResult}");


                    if (DealKey == "压缩")
                    {
                        if (HandleSupList.Contains(sFullPath))
                        {
                            HandleSupList.Remove(sFullPath);//移除处理中列表
                        }

                        if (sExecResult == "allfalse")
                        {
                            Logger.Instance.Log($"{sFullPath}的压缩公式{sExecFormula}分支全部不成立，用原值");
                            CacheUseProp(sFullPath, "SUP");
                        }
                        else if (bool.TryParse(sExecResult, out bool boolValue))
                        {
                            Dictionary<object, string> retrievedObjectDict = GetObjectFromAssemblyByHierarchy(lFullPath, objectType);
                            var firstKeyValuePair = retrievedObjectDict.First();
                            object oObj = firstKeyValuePair.Key;
                            string sObjType = firstKeyValuePair.Value;
                            SetObjectValue(oObj, sObjType, DealKey, sExecResult, lFullPath);
                            CacheUseProp(sFullPath, "SUP", sObjType);
                        }
                        else
                        {
                            Logger.Instance.Log($"{sFullPath}的压缩公式计算出来的值{sExecResult}不为bool，请检查公式{sExecFormula}");
                            CacheUseProp(sFullPath, "SUP");
                        }
                        
                    }
                    else if (DealKey == "尺寸")
                    {
                        if (sExecResult == "allfalse")
                        {
                            Logger.Instance.Log($"{sFullPath}的尺寸公式{sExecFormula}分支全部不成立，用原值");
                            CacheUseProp(sFullPath, "DIM");
                        }
                        else if (double.TryParse(sExecResult, out double doubleValue))
                        {
                            Dictionary<object, string> retrievedObjectDict = GetObjectFromAssemblyByHierarchy(lFullPath, objectType);
                            var firstKeyValuePair = retrievedObjectDict.First();
                            object oObj = firstKeyValuePair.Key;
                            string sObjType = firstKeyValuePair.Value;
                            SetObjectValue(oObj, sObjType, DealKey, sExecResult, lFullPath);
                            CacheUseProp(sFullPath, "DIM", sObjType);
                        }
                        else
                        {
                            Logger.Instance.Log($"{sFullPath}的尺寸公式计算出来的值{sExecResult}不为数值，请检查公式{sExecFormula}");
                            CacheUseProp(sFullPath, "DIM");
                        }

                        if (HandleDimList.Contains(sFullPath))
                        {
                            HandleDimList.Remove(sFullPath);//移除处理中列表
                        }

                    }
                    else if (DealKey == "替换")
                    {
                        if (HandleRepList.Contains(sFullPath))
                        {
                            HandleRepList.Remove(sFullPath);//移除处理中列表
                        }
                        if (sExecResult == "allfalse")
                        {
                            Logger.Instance.Log($"{sFullPath}的替换公式{sExecFormula}分支全部不成立，用原值");
                            // 替换不需要记录，应该不会有其他部件和替换的部件用同一个路径去替换吧
                            //CacheUseProp(sFullPath, "SUP");
                        }
                        else if (File.Exists(sExecResult))
                        {
                            Dictionary<object, string> retrievedObjectDict = GetObjectFromAssemblyByHierarchy(lFullPath, objectType);
                            var firstKeyValuePair = retrievedObjectDict.First();
                            object oObj = firstKeyValuePair.Key;
                            string sObjType = firstKeyValuePair.Value;
                            SetObjectValue(oObj, sObjType, DealKey, sExecResult, lFullPath);
                            //CacheUseProp(sFullPath, "SUP", sObjType);
                        }
                        else
                        {
                            Logger.Instance.Log($"{sFullPath}的替换公式计算出来的值{sExecResult}不存在，请检查公式{sExecFormula}");
                            //CacheUseProp(sFullPath, "SUP");
                        }
                    }
                    else if (DealKey == "方程式曲线")
                    {
                        try
                        {
                            Dictionary<object, string> retrievedObjectDict = GetObjectFromAssemblyByHierarchy(lFullPath, objectType);
                            var firstKeyValuePair = retrievedObjectDict.First();
                            object oObj = firstKeyValuePair.Key;
                            string sObjType = firstKeyValuePair.Value;
                            SetObjectValue(oObj, sObjType, DealKey, sExecResult, lFullPath);
                            //CacheUseProp(sFullPath, "SUP", sObjType);
                        }
                        catch(Exception ex)
                        {
                            Logger.Instance.Log($"{sFullPath}的替换公式计算出来的值{sExecResult}不存在，请检查公式{sExecFormula}");
                            Logger.Instance.Log($"驱动方程式曲线失败 {ex.Message}");
                            //CacheUseProp(sFullPath, "SUP");
                        }
                    }

                    inputDict[sFullPath] = "done";
                }
            }
        }
        /// </summary>
        ///	使用NCalc计算数学表达式的值，并返回值
        /// </summary>
        public static double CalculateExpression(string expression)
        {
            // 移除单引号
            expression = expression.Replace("'", "");

            // 使用NCalc计算表达式的值.
            Expression e = new Expression(expression);
            if (e.HasErrors())
            {
                throw new ArgumentException("Invalid expression.");
            }

            var result = (object[])e.Evaluate();
            return Convert.ToDouble(result);
        }//工具方法{暂时}
        /// </summary>
        ///	缓存驱动属性
        /// </summary>
        public void CacheUseProp(string sFormulaFullPath, string sUseType, string objectType = null)
        {
            List<string> lFullPath = CommonTools.Instance.SplitStringByCustomSeparator(sFormulaFullPath, Defines.Comp_Split);
            Dictionary<object, string> retrievedObjectDict = GetObjectFromAssemblyByHierarchy(lFullPath, objectType);
            //这里增加一个初始值
            var firstKeyValuePair = retrievedObjectDict.First();
            object oObj = firstKeyValuePair.Key;
            string sObjType = firstKeyValuePair.Value;
            switch (sUseType)
            {
                case "DIM":
                    switch (sObjType.ToLower())
                    {
                        case "尺寸驱动":
                            IDimension oDim = (IDimension)oObj;
                            Feature OwnFeature = oDim.GetFeatureOwner();
                            int type = 0;
                            if(OwnFeature != null)
                            {
                                IDisplayDimension oDispDim = OwnFeature.GetFirstDisplayDimension();
                                while(oDispDim != null)
                                {
                                    if(oDispDim.GetDimension() == oDim)
                                    {
                                        type = oDispDim.GetType();
                                        break;
                                    }
                                    oDispDim = OwnFeature.GetNextDisplayDimension(oDispDim);
                                }
                                    
                            }
                            else
                            {
                                Logger.Instance.Log($"获取尺寸{sFormulaFullPath}的特征失败");
                            }
                            //IDisplayDimension dispDim = (IDisplayDimension)oObj;
                            double dimensionValue = oDim.Value;
                            switch ((swDimensionType_e)type)
                            {
                                case swDimensionType_e.swLinearDimension:            // 线性尺寸
                                case swDimensionType_e.swChamferDimension:      // 倒角长度
                                case swDimensionType_e.swRadialDimension:             // 半径尺寸
                                    dimensionValue = dimensionValue / 1000.0; // 米 → 毫米
                                    break;

                                case swDimensionType_e.swAngularDimension:            // 角度尺寸
                                    dimensionValue = dimensionValue * (180.0 / Math.PI); // 弧度 → 角度
                                    break;
                                default:
                                    dimensionValue = dimensionValue; // 默认直接返回（小心，这可能还需要扩展）
                                    break;
                            }
                            CacheDimValue[sFormulaFullPath] = dimensionValue;
                            Logger.Instance.Log($"尺寸{sFormulaFullPath}的数值为{dimensionValue}");
                            break;
                        case "特征压缩":
                            Logger.Instance.Log($"无法从特征{sFormulaFullPath}中获取尺寸值，请检查");
                            MessageBox.Show($"无法从特征{sFormulaFullPath}中获取尺寸值，请检查");
                            break;
                        case "配合驱动":
                            IFeature oMateFea = (IFeature)oObj;
                            IMate2 mate = oMateFea.GetSpecificFeature2() as IMate2;

                            if (mate != null)
                            {
                                if (mate.Type == (int)swMateType_e.swMateDISTANCE)
                                {
                                    IDistanceMateFeatureData distanceData = mate.MateEntity(0) as IDistanceMateFeatureData;
                                    if (distanceData != null)
                                    {
                                        double distanceValue = distanceData.Distance;
                                        CacheDimValue[sFormulaFullPath] = distanceValue;
                                        Logger.Instance.Log($"距离配合{sFormulaFullPath}的数值为{distanceValue}");
                                    }
                                }
                                else if (mate.Type == (int)swMateType_e.swMateANGLE)
                                {
                                    IAngleMateFeatureData angleData = mate.MateEntity(0) as IAngleMateFeatureData;
                                    if (angleData != null)
                                    {
                                        double angleValue = angleData.Angle;
                                        CacheDimValue[sFormulaFullPath] = angleValue;
                                        Logger.Instance.Log($"角度配合{sFormulaFullPath}的数值为{angleValue}");
                                    }
                                }
                                else
                                {
                                    Logger.Instance.Log($"无法从配合{sFormulaFullPath}中获取尺寸值，请检查");
                                    MessageBox.Show($"无法从配合{sFormulaFullPath}中获取尺寸值，请检查");
                                }
                            }
                            break;
                        case "零部件":
                            Logger.Instance.Log($"无法从零部件{sFormulaFullPath}中获取尺寸值，请检查");
                            MessageBox.Show($"无法从零部件{sFormulaFullPath}中获取尺寸值，请检查");
                            break;
                        case "方程式常量":
                            Logger.Instance.Log($"方程式常量不需要缓存，不会使用到");
                            break;
                        default:
                            Logger.Instance.Log($"CacheUseProp - DIM 对象类型不符合预设");
                            MessageBox.Show($"CacheUseProp - DIM 对象类型不符合预设");
                            break;
                    }
                    break;
                case "SUP":
                    switch (sObjType.ToLower())
                    {
                        case "尺寸驱动":
                            Logger.Instance.Log($"无法从{sFormulaFullPath}中获取压缩值，请检查");
                            MessageBox.Show($"无法从{sFormulaFullPath}中获取压缩值，请检查");
                            break;
                        case "特征压缩":
                            IFeature oFeature = (IFeature)oObj;
                            bool isFeatureSuppressed = oFeature.IsSuppressed();
                            CacheSupState[sFormulaFullPath] = isFeatureSuppressed;
                            Logger.Instance.Log($"特征{sFormulaFullPath}的压缩值为{isFeatureSuppressed}");
                            break;
                        case "配合驱动":
                            IFeature oMateFea = (IFeature)oObj;
                            IMate2 mate = oMateFea.GetSpecificFeature2() as IMate2;
                            if (mate != null)
                            {
                                bool isMateSuppressed = oMateFea.IsSuppressed();
                                CacheSupState[sFormulaFullPath] = isMateSuppressed;
                                Logger.Instance.Log($"配合{sFormulaFullPath}的压缩值为{isMateSuppressed}");
                            }
                            else
                            {
                                Logger.Instance.Log($"获取配合{sFormulaFullPath}的压缩属性失败");
                            }
                            Logger.Instance.Log($"");
                            break;
                        case "零部件":
                            //0、1是被压缩了，2、3、4是没压缩，5是解析错误
                            List<int> supList = new List<int> {
                                (int)swComponentSuppressionState_e.swComponentSuppressed ,
                                (int)swComponentSuppressionState_e.swComponentLightweight ,
                            };
                            IComponent2 oComp = (IComponent2)oObj;
                            int suppressionState = oComp.GetSuppression();
                            bool bSuppress = true;
                            if (suppressionState == (int)swComponentSuppressionState_e.swComponentInternalIdMismatch)
                            {
                                Logger.Instance.Log($"零部件{sFormulaFullPath}可能无法正确加载");
                            }
                            else if (supList.Contains(suppressionState))
                            {
                                bSuppress = true;
                            }
                            else
                            {
                                bSuppress = false;
                            }
                            CacheSupState[sFormulaFullPath] = bSuppress;
                            Logger.Instance.Log($"零部件{sFormulaFullPath}的压缩值为{suppressionState}");
                            break;
                        case "方程式常量":
                            Logger.Instance.Log($"方程式常量不需要缓存，不会使用到");
                            break;
                        default:
                            Logger.Instance.Log($"CacheUseProp - SUP 对象类型不符合预设");
                            MessageBox.Show($"CacheUseProp - SUP 对象类型不符合预设");
                            break;
                    }
                    break;
                default:
                    Logger.Instance.Log($"CacheUseProp 驱动类型不符合预设");
                    MessageBox.Show($"CacheUseProp 驱动类型不符合预设");
                    break;
            }

        }
        /// </summary>
        ///设置对象的值
        /// </summary>
        public void SetObjectValue(object obj, string objectType, string setType, string resultValue, List<string> lFullPath)
        {
            IModelDoc2 oActiveDoc = GetActiveDocument();
            IModelDoc2 oTargetDoc = _commonInterface.GetTargetModelDoc2(lFullPath, oActiveDoc);
            IComponent2 oTargetComponent = _commonInterface.GetTargetComponent(lFullPath, oActiveDoc);

            SelectionMgr swSelMgr = oActiveDoc.SelectionManager;
            SelectData swSelData = swSelMgr.CreateSelectData();
            oActiveDoc.ClearSelection2(true);

            switch (setType.ToLower())
            {
                case "尺寸":
                    switch (objectType.ToLower())
                    {
                        case "方程式常量":
                            
                            lFullPath.RemoveAt(lFullPath.Count - 1);
                           CommonTools.Instance.UpdateEquation(oTargetDoc, (string)obj, resultValue);
                            break;
                        case "尺寸驱动":
                            if (obj is IDimension dimension)
                            {
                                if (double.TryParse(resultValue, out double newDimensionValue))
                                {
                                    Feature OwnFeature = dimension.GetFeatureOwner();
                                    int type = 0;
                                    if (OwnFeature != null)
                                    {
                                        IDisplayDimension oDispDim = OwnFeature.GetFirstDisplayDimension();
                                        while (oDispDim != null)
                                        {
                                            if (oDispDim.GetDimension() == dimension)
                                            {
                                                type = oDispDim.GetType();
                                                break;
                                            }
                                            oDispDim = OwnFeature.GetNextDisplayDimension(oDispDim);
                                        }
                                    }
                                    switch ((swDimensionType_e)type)
                                    {
                                        case swDimensionType_e.swAngularDimension:            // 角度尺寸
                                            newDimensionValue = newDimensionValue * (Math.PI / 180.0); // 角度 → 弧度
                                            break;
                                        default:
                                            // 默认直接使用原值
                                            break;
                                    }
                                   dimension.SetSystemValue3(newDimensionValue, (int)swSetValueInConfiguration_e.swSetValue_InAllConfigurations, null);    
                                }
                                else
                                {
                                    Logger.Instance.Log("Invalid dimension value.");
                                }
                            }
                            break;

                        case "配合驱动":
                            if (obj is IMate2 mate)
                            {
                                if (double.TryParse(resultValue, out double mateValue))
                                {
                                    IFeature mateFeature = mate as IFeature;
                                    IFeature mateFeatureByName = mateFeature;
                                    string sFeatureName = mateFeature.Name;
                                    if (oTargetComponent != null)
                                    {
                                        ModifyMateInComp(oActiveDoc, mate, mateValue, oTargetComponent);
                                        break;
                                    }
                                    MateFeatureData swMateData = (MateFeatureData)mateFeatureByName.GetDefinition();
                                    switch (mate.Type)
                                    {
                                        case (int)swMateType_e.swMateDISTANCE:
                                            DistanceMateFeatureData swDistMateData = (DistanceMateFeatureData)swMateData;
                                            if (swDistMateData != null)
                                            {
                                                swDistMateData.Distance = mateValue;
                                                swDistMateData.MaximumDistance = mateValue;
                                                swDistMateData.MinimumDistance = mateValue;
                                            }
                                            AssemblyDoc swAssy = (AssemblyDoc)oActiveDoc;
                                            bool boolstatus = mateFeatureByName.ModifyDefinition(swDistMateData, oActiveDoc, null);
                                            swAssy.EditAssembly();
                                            break;

                                        case (int)swMateType_e.swMateANGLE:
                                            IAngleMateFeatureData angleData = (IAngleMateFeatureData)swMateData;
                                            if (angleData != null)
                                            {
                                                angleData.Angle = mateValue;
                                            }
                                            swAssy = (AssemblyDoc)oActiveDoc;
                                            boolstatus = mateFeatureByName.ModifyDefinition(angleData, oActiveDoc, null);
                                            swAssy.EditAssembly();
                                            break;

                                        default:
                                            Logger.Instance.Log("这个配合无法被设置尺寸");
                                            break;
                                    }
                                }
                                else
                                {
                                    Logger.Instance.Log("Invalid mate value.");
                                }
                            }
                            break;

                        default:
                            Logger.Instance.Log($"Unsupported object type for set type '{setType}': {objectType}");
                            break;
                    }
                    break;

                case "压缩":
                    switch (objectType.ToLower())
                    {
                        case "方程式常量":
                            lFullPath.RemoveAt(lFullPath.Count - 1);
                            CommonTools.Instance.UpdateEquation(oTargetDoc, (string)obj, resultValue);
                            break;
                        case "特征压缩":
                            if (obj is IFeature feature)
                            {
                                if (bool.TryParse(resultValue, out bool isSuppressed))
                                {
                                    bool success = feature.Select2(false,0);
                                    if(!success)
                                    {
                                        Logger.Instance.Log("Select2 选择失败！");
                                    }
                                    if (isSuppressed)
                                    {
                                        oActiveDoc.EditSuppress2();
                                    }
                                    else
                                    {
                                        oActiveDoc.EditUnsuppress2();
                                        Logger.Instance.Log("");
                                    }
                                }
                                else
                                {
                                    Logger.Instance.Log("Invalid suppression value.");
                                }
                            }
                            break;
                        case "配合驱动":
                            if (obj is IMate2 mate)
                            {
                                if (bool.TryParse(resultValue, out bool isSuppressed))
                                {
                                    IFeature mateFeature = mate as IFeature;

                                    if (mateFeature != null)
                                    {
                                        // 设置特征的压缩状态
                                        mateFeature.SetSuppression2(isSuppressed ? (int)swFeatureSuppressionAction_e.swSuppressFeature : (int)swFeatureSuppressionAction_e.swUnSuppressFeature, 0, null);
                                    }
                                    else
                                    {
                                        Logger.Instance.Log("Unable to get the feature associated with the mate.");
                                    }
                                }
                                else
                                {
                                    Logger.Instance.Log("Invalid suppression value.");
                                }
                            }
                            break;
                        case "零部件":
                            if (obj is IComponent2 component)
                            {
                                if (bool.TryParse(resultValue, out bool isSuppressed))
                                {
                                    swComponentSuppressionState_e suppressionState = isSuppressed
                                        ? swComponentSuppressionState_e.swComponentSuppressed
                                        : swComponentSuppressionState_e.swComponentFullyResolved;
                                    component.SetSuppression2((int)suppressionState);
                                    //oTargetDoc.ClearSelection2(true);
                                    //component.Select4(false, swSelData, false);
                                    //if (isSuppressed)
                                    //{
                                    //    //oTargetDoc.EditSuppress2();
                                    //}
                                    //else
                                    //{
                                    //    component.SetSuppression2((int)swComponentSuppressionState_e.swComponentFullyResolved);
                                    //}
                                }
                                else
                                {
                                    Logger.Instance.Log("Invalid suppression value.");
                                }
                            }
                            break;

                        default:
                            Logger.Instance.Log($"Unsupported object type for set type '{setType}': {objectType}");
                            break;
                    }
                    break;

                case "替换":
                    switch (objectType.ToLower())
                    {
                        case "零部件":
                            if (obj is IComponent2 component)
                            {
                                IModelDoc2 modelDoc = GetActiveDocument();
                                ModelDocExtension swModelDocExt = (ModelDocExtension)modelDoc.Extension;
                                ISelectionMgr selectionMgr = modelDoc.SelectionManager;
                                SelectData SwSelData = selectionMgr.CreateSelectData();
                                IAssemblyDoc assemblyDoc = (IAssemblyDoc)modelDoc;
                                bool status = false;
                                // 获取组件的文件路径
                                string componentFilePath = component.GetPathName();
                                Logger.Instance.Log($"组件 {component.Name2} 的文件路径为：{componentFilePath}");
                                if(componentFilePath != resultValue)
                                {
                                    // 替换组件
                                    string ReferencedConfiguration = component.ReferencedConfiguration;
                                    Logger.Instance.Log($"ReferencedConfiguration = {ReferencedConfiguration}");
                                    status = component.Select4(false, SwSelData, false);
                                    Logger.Instance.Log($"select status1 = {status}");
                                    status = assemblyDoc.ReplaceComponents2(resultValue, ReferencedConfiguration, true, 0, true);
                                    Logger.Instance.Log($"ReplaceComponents status = {status}");
                                    Logger.Instance.Log($"已将组件 {component.Name2} 替换为 {resultValue}");
                                }
                                string elementName = lFullPath[lFullPath.Count - 1];
                                string MATEsimpleName = elementName.Split(new string[] { Defines.Parent_Split }, StringSplitOptions.None)[0];
                                string simpleName = MATEsimpleName.Split(new string[] { Defines.UseValue_Split }, StringSplitOptions.None)[0];
                                SetReplaceCompName(simpleName, component.Name2);
                                return;
                            }
                            break;

                        default:
                            Logger.Instance.Log($"Unsupported object type for set type '{setType}': {objectType}");
                            break;
                    }
                    break;

                case "方程式曲线":
                    if (obj is SketchSegment targetSegment)
                    {
                        try
                        {
                            if (targetSegment.GetType() == (int)swSketchSegments_e.swSketchSPLINE)
                            {
                                SketchSpline spline = targetSegment as SketchSpline;
                                if (spline != null)
                                {
                                    spline.GetEquationParameters2(
                                        out string XExpression, 
                                        out string YExpression,
                                        out string ZExpression,
                                        out double RangeStart,
                                        out double RangeEnd,
                                        out bool IsAngleRange,
                                        out double RotationAngle,
                                        out double xOff, 
                                        out double yOff, 
                                        out bool LockStart, 
                                        out bool LockEnd
                                        );
                                    Dictionary<string, string> ParaDict = CommonTools.ParseFormulaString(resultValue);
                                    if (ParaDict.ContainsKey("y"))
                                    {
                                        bool isValidy = double.TryParse(ParaDict["y"], out double yexp);
                                        if (isValidy)
                                        {
                                            YExpression = yexp.ToString();
                                        }
                                        else
                                        {
                                            string yExpression = ParaDict["y"];
                                            string execbegin = yExpression.Split(new[] { "*sin(" }, StringSplitOptions.None)[0].Split(new[] { "*cos(" }, StringSplitOptions.None)[0];
                                            string execend = yExpression.Split(new[] { execbegin }, StringSplitOptions.None)[1];

                                            execbegin = execbegin.Replace("÷", "/");
                                            Expression e = new Expression(execbegin);
                                            object result;
                                            try
                                            {
                                                result = e.Evaluate();
                                                YExpression = result.ToString() + execend;
                                            }
                                            catch (Exception ex)
                                            {
                                                Logger.Instance.Log($"无法解析y表达式: {ParaDict["y"]} \n\n {ex.Message}");
                                                result = execbegin;
                                                YExpression = result + execend;
                                            }
                                            
                                        }
                                            
                                    }
                                    if(ParaDict.ContainsKey("x1"))
                                    {
                                        bool isValidx1 = double.TryParse(ParaDict["x1"], out double xexp1);
                                        if (isValidx1)
                                        {
                                            RangeStart = xexp1;
                                        }
                                        else
                                        {
                                            string x1Expression = ParaDict["x1"];
                                            x1Expression = x1Expression.Replace("÷", "/");
                                            Expression e = new Expression(x1Expression);
                                            object result;
                                            try
                                            {
                                                result = e.Evaluate();
                                            }
                                            catch (Exception ex)
                                            {
                                                Logger.Instance.Log($"无法解析x1表达式: {x1Expression} \n\n {ex.Message}");
                                                result = x1Expression;
                                            }
                                            RangeStart = (double)result;
                                        }
                                        //RangeStart = double.Parse(ParaDict["x1"]);
                                    }
                                    if (ParaDict.ContainsKey("x2"))
                                    {
                                        bool isValidx2 = double.TryParse(ParaDict["x2"], out double xexp2);
                                        if (isValidx2)
                                        {
                                            RangeEnd = xexp2;
                                        }
                                        else
                                        {
                                            string x2Expression = ParaDict["x2"];
                                            x2Expression = x2Expression.Replace("÷", "/");
                                            Expression e = new Expression(x2Expression);
                                            object result;
                                            try
                                            {
                                                result = e.Evaluate();
                                            }
                                            catch (Exception ex)
                                            {
                                                Logger.Instance.Log($"无法解析x2表达式: {x2Expression} \n\n {ex.Message}");
                                                result = x2Expression;
                                            }
                                            RangeEnd = (double)result;
                                        }
                                    }
                                    // ✅ 成功找到并可以修改方程式曲线参数了
                                    spline.SetEquationParameters2(XExpression, YExpression, ZExpression, RangeStart, RangeEnd, IsAngleRange, RotationAngle, xOff, yOff, LockStart, LockEnd);
                                    Logger.Instance.Log("✅ 成功修改方程式驱动曲线！");
                                }
                                else
                                {
                                    Logger.Instance.Log("❌ 目标SketchSegment不是SketchSpline，无法设置方程式！");
                                }
                            }
                            else
                            {
                                Logger.Instance.Log("❌ 找到的SketchSegment不是方程式曲线！");
                            }
                        }catch(Exception ex)
                        {
                            Logger.Instance.Log($"驱动方程式曲线失败 = {ex.Message}");
                        }
                    }
                    break;

                default:
                    Logger.Instance.Log($"Unsupported set type: {setType}");
                    break;
            }
        }
        /// </summary>
        ///在子装配体文档，修改指定配合（Mate）的尺寸或角度值
        /// </summary>
        public void ModifyMateInComp(IModelDoc2 oActiveDoc, IMate2 mate, double mateValue, IComponent2 oTargetComponent)
        {
            // 假设oActiveDoc是顶层装配体A的ModelDoc2
            // 假设oTargetComponent是子装配体B的Component2

            // 获取原始顶层装配体的文档名
            string originalDocName = oActiveDoc.GetTitle();

            // 激活子装配体文档
            ModelDoc2 oSubAssyDoc = oTargetComponent.GetModelDoc2();
            string subAssyName = oSubAssyDoc.GetTitle();
            int errors = 0;

            ModelDoc2 activatedDoc = (ModelDoc2)iSwApp.ActivateDoc3(subAssyName, true, (int)swRebuildOnActivation_e.swDontRebuildActiveDoc, ref errors);

            // 确认激活成功
            if (activatedDoc != oSubAssyDoc)
            {
                Logger.Instance.Log($"❌ 激活子装配体文档失败：{subAssyName}");
                return;
            }

            // 现在上下文位于子装配体内，可以安全修改配合
            IFeature mateFeature = mate as IFeature;
            string sFeatureName = mateFeature.Name;
            IFeature mateFeatureByName = (activatedDoc as AssemblyDoc).FeatureByName(sFeatureName);

            MateFeatureData swMateData = (MateFeatureData)mateFeatureByName.GetDefinition();

            switch (mate.Type)
            {
                case (int)swMateType_e.swMateDISTANCE:
                    DistanceMateFeatureData swDistMateData = (DistanceMateFeatureData)swMateData;
                    if (swDistMateData != null)
                    {
                        swDistMateData.Distance = mateValue;
                        swDistMateData.MaximumDistance = mateValue;
                        swDistMateData.MinimumDistance = mateValue;
                    }

                    bool boolstatus = mateFeatureByName.ModifyDefinition(swDistMateData, oSubAssyDoc, null);
                    ((AssemblyDoc)oSubAssyDoc).EditAssembly();
                    break;

                case (int)swMateType_e.swMateANGLE:
                    IAngleMateFeatureData angleData = (IAngleMateFeatureData)swMateData;
                    if (angleData != null)
                    {
                        angleData.Angle = mateValue;
                    }

                    boolstatus = mateFeatureByName.ModifyDefinition(angleData, oSubAssyDoc, null);
                    ((AssemblyDoc)oSubAssyDoc).EditAssembly();
                    break;

                default:
                    Logger.Instance.Log("这个配合无法被设置尺寸");
                    break;
            }

            // 修改完成后，重新激活顶层装配体文档（恢复初始上下文）
            ModelDoc2 restoredDoc = (ModelDoc2)iSwApp.ActivateDoc3(originalDocName, true, (int)swRebuildOnActivation_e.swDontRebuildActiveDoc, ref errors);

            if (restoredDoc != oActiveDoc)
            {
                Logger.Instance.Log($"❌ 恢复顶层装配体文档失败：{originalDocName}");
            }

        }//工具方法（solidwork）
        /// </summary>
        ///根据给定记录名称，返回已替换的组件简单名（如果存在替换记录），否则返回原名。
        /// </summary>
        public string GetReplaceCompName(string sRecordName)
        {
            if (Replace_Simple_Name.ContainsKey(sRecordName))
            {
                return Replace_Simple_Name[sRecordName];
            }
            else
            {
                return sRecordName;
            }
        }
        /// </summary>
        ///保存或更新组件名称替换映射，将指定记录名称映射为新的组件名称。
        /// </summary>
        //配置
        public void SetReplaceCompName(string sRecordName, string sNewCompName)
        {
            Replace_Simple_Name[sRecordName] = sNewCompName;
        }

        #endregion
        #region 捕获选中
        /// <summary>
        /// 注册选择事件监听器
        /// </summary>
        private int ConnectSelectionNotify()
        {
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;
            if (activeDoc != null)
            {
                // 注册选择更改事件
                if (activeDoc is PartDoc partDoc)
                {
                    ((DPartDocEvents_Event)partDoc).UserSelectionPostNotify += OnNewSelectionNotify;
                }
                else if (activeDoc is AssemblyDoc assemblyDoc)
                {
                    ((DAssemblyDocEvents_Event)assemblyDoc).UserSelectionPostNotify += OnNewSelectionNotify;
                }

            }
            return 0;
        }
        /// <summary>
        /// 注销选择事件监听器
        /// </summary>
        private int DisConnectSelectionNotify()
        {
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;
            if (activeDoc != null)
            {
                // 注册选择更改事件
                if (activeDoc is PartDoc partDoc)
                {
                    ((DPartDocEvents_Event)partDoc).UserSelectionPostNotify -= OnNewSelectionNotify;
                }
                else if (activeDoc is AssemblyDoc assemblyDoc)
                {
                    ((DAssemblyDocEvents_Event)assemblyDoc).UserSelectionPostNotify -= OnNewSelectionNotify;
                }

            }
            return 0;
        }
        /// <summary>
        ///选择事件回调函数
        /// <remarks>
        /// 用于在用户选择模型对象时，自动识别其类型与路径，并生成唯一标识传递给插件界面，用于跟踪、显示或进一步操作。
        ///<remarks>
        private int OnNewSelectionNotify()
        {
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;
            ISelectionMgr selectionMgr = (ISelectionMgr)activeDoc.SelectionManager;
            SelectData SwSelData = selectionMgr.CreateSelectData();
            int selectedCount = selectionMgr.GetSelectedObjectCount2(-1);

            byte[] SelectID = null;
            string sName = "";
            string sRecordName = "";
            List<string> lSreachList;

            Face2 SwFace;
            Edge SwEdge;
            Feature SwFeature;
            DisplayDimension SwDisDimension;
            Component2 SwComponent = null;
            Feature SwMateFeature;
            ISketchSegment SwSketchSegs;
            Feature SwOtherFeature;
            List<string> lOtherFeature = new List<string>
            {
                "swSelFTRFOLDER",
                "swSelCOMPPATTERN",
                "swSelSKETCHES",
                "swSelDATUMPLANES",
            };

            Logger.Instance.Log($"select coubnt {selectedCount}");
            if (selectedCount > 0)
            {
                // object selectedObject = selectionMgr.GetSelectedObject6(1, -1);
                string SelType = ((swSelectType_e)selectionMgr.GetSelectedObjectType3(selectedCount, -1)).ToString().Trim();
                if (SelType == "swSelFACES")
                {
                    SwFace = (Face2)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    Feature SwFeatureByFace = (Feature)SwFace.GetFeature();
                    if (dRecordFeatureTypes.TryGetValue(SwFeatureByFace.GetTypeName2(), out var properties))
                    {
                        sName = SwFeatureByFace.Name;
                        activeDoc.ClearSelection2(true);
                        Entity SwEntityToSelect = (Entity)SwFeatureByFace;
                        SwEntityToSelect.Select4(false, SwSelData);
                        SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwFeatureByFace);
                    }
                    else
                    {
                        Logger.Instance.Log($"暂未支持的特征类型-swSelFACES：{SwFeatureByFace.GetTypeName2()}");
                        taskPaneHost.OnCatchFail($"暂未支持的特征类型-swSelFACES：{SwFeatureByFace.GetTypeName2()}");
                        return 0;
                    }
                }
                else if (SelType == "swSelEDGES")
                {
                    SwEdge = (Edge)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    Feature SwFeatureByEdge = CommonTools.Instance.GetFeatureFromEdge(SwEdge);
                    if (SwFeatureByEdge == null)
                    {
                        Logger.Instance.Log($"暂未支持的选中类型-swSelEDGES1：{SelType}");
                        taskPaneHost.OnCatchFail($"暂未支持的选中类型-swSelEDGES1：{SelType}");
                        return 0;
                    }
                    else
                    {
                        if (dRecordFeatureTypes.TryGetValue(SwFeatureByEdge.GetTypeName2(), out var properties))
                        {
                            sName = SwFeatureByEdge.Name;
                            SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwFeatureByEdge);
                        }
                        else
                        {
                            Logger.Instance.Log($"暂未支持的选中类型-swSelEDGES2：{SwFeatureByEdge.GetTypeName2()}");
                            taskPaneHost.OnCatchFail($"暂未支持的选中类型-swSelEDGES2：{SwFeatureByEdge.GetTypeName2()}");
                            return 0;
                        }

                    }
                }
                else if (SelType == "swSelBODYFEATURES")
                {
                    SwFeature = (Feature)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    if (dRecordFeatureTypes.TryGetValue(SwFeature.GetTypeName2(), out var properties))
                    {
                        sName = SwFeature.Name;
                        SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwFeature);
                    }
                    else
                    {
                        Logger.Instance.Log($"暂未支持的特征类型-swSelBODYFEATURES：{SwFeature.GetTypeName2()}");
                        taskPaneHost.OnCatchFail($"暂未支持的特征类型-swSelBODYFEATURES：{SwFeature.GetTypeName2()}");
                        return 0;
                    }
                }
                else if (SelType == "swSelDIMENSIONS")
                {
                    SwDisDimension = (DisplayDimension)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    Dimension SwDimension = (Dimension)SwDisDimension.GetDimension(); // 获取对应的 Dimension 对象
                    sName = SwDimension.GetNameForSelection();
                    SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwDisDimension);
                }
                else if (SelType == "swSelCOMPONENTS")
                {
                    SwComponent = (Component2)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    sName = SwComponent.Name2;
                    SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwComponent);
                }
                else if (SelType == "swSelMATES")
                {
                    SwMateFeature = (Feature)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    Feature SwMate = (Feature)SwMateFeature.GetSpecificFeature2();
                    SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwMateFeature);
                    sName = SwMate.Name;
                }
                else if (SelType == "swSelSKETCHSEGS")
                {
                    SwSketchSegs = (ISketchSegment)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    //Sketch ssketch = SwSketchSegs.GetSketch();
                    sName = SwSketchSegs.GetName();
                    SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwSketchSegs);
                }
                else if(lOtherFeature.Contains(SelType))
                {
                    SwOtherFeature = (Feature)selectionMgr.GetSelectedObject6(selectedCount, -1);
                    sName = SwOtherFeature.Name;
                    SelectID = (byte[])activeDoc.Extension.GetPersistReference3(SwOtherFeature);
                }
                else
                {
                    taskPaneHost.OnCatchFail($"暂未支持的特征类型：{SelType}");
                }

                if (string.IsNullOrEmpty(sName))
                {
                    return 0;
                }

                string sRelativeComponentName = GetRelativeComponentName(SelectID);

                if (string.IsNullOrEmpty(sRelativeComponentName))
                {
                    sRelativeComponentName = activeDoc.GetTitle();
                }

                if (sRelativeComponentName == activeDoc.GetTitle())
                {
                    lSreachList = new List<string> { sRelativeComponentName };
                }
                else
                {
                    lSreachList = GetComponentFileNames(sRelativeComponentName, activeDoc);
                }

                if (SelType == "swSelCOMPONENTS")
                {
                    string sCompName;
                    bool bNeedInsertExtra = false;
                    //sRecordName = GetParentComponentPath(SwComponent, activeDoc);

                    if (lSreachList.Count == 1) //说明选中了主装配体中的第一层部件
                    {
                        bNeedInsertExtra = true;
                    }

                    lSreachList.RemoveAt(lSreachList.Count - 1); //去尾，最后一个元素原本为部件的文件名

                    if (lSreachList.Count >= 1) //数据结构为主装配体->所有的部件列表，因此定位时不需要根据完整的层级信息定位
                    {
                        lSreachList = lSreachList.GetRange(lSreachList.Count - 1, 1); //追溯时保留最后一层即可
                        sRecordName = Regex.Replace(string.Join("/", lSreachList), @"(?i)\.sldprt|\.sldasm", ""); //生成部件的唯一标识名
                    }
                    else
                    {
                        // 如果列表的元素少于2个，直接保留现有的所有元素
                        Logger.Instance.Log("lSreachList contains less than 1 elements.");
                        sRecordName = Regex.Replace(activeDoc.GetTitle(), @"(?i)\.sldprt|\.sldasm", ""); //生成部件的唯一标识名
                    }


                    lSreachList.Insert(0, activeDoc.GetTitle());//定位时用到的顶级主装配体名

                    if (bNeedInsertExtra) //说明选中了主装配体中的第一层部件，主装配体也存在部件列表中
                    {
                        lSreachList.Insert(1, activeDoc.GetTitle()); //选中零部件，需要在索引第二层再加一个主装配体名
                    }

                    if (activeDoc.GetType() == (int)swDocumentTypes_e.swDocPART)
                    {
                        sCompName = sName + ".SLDPRT";
                    }
                    else if (activeDoc.GetType() == (int)swDocumentTypes_e.swDocASSEMBLY)
                    {
                        sCompName = sName + ".SLDASM";
                    }
                    else
                    {
                        sCompName = sName;
                    }


                    if (sCompName != sRelativeComponentName)
                    {
                        string[] components = sName.Split('/');
                        sName = components[components.Length - 1];
                    }
                    else
                    {
                        return 0;
                    }
                }
                else
                {

                    if (lSreachList.Count >= 1)
                    {
                        lSreachList = lSreachList.GetRange(lSreachList.Count - 1, 1);
                        sRecordName = Regex.Replace(string.Join("/", lSreachList), @"(?i)\.sldprt|\.sldasm", "");
                    }
                    else
                    {
                        // 如果列表的元素少于2个，直接保留现有的所有元素
                        Logger.Instance.Log("lSreachList contains less than 1 elements.");
                        sRecordName = Regex.Replace(activeDoc.GetTitle(), @"(?i)\.sldprt|\.sldasm", ""); //生成部件的唯一标识名
                    }
                    lSreachList.Insert(0, activeDoc.GetTitle());

                }
                lSreachList.Add(sName + Defines.Parent_Split + sRecordName);

                taskPaneHost.OnSelectElement(lSreachList);

            }
            return 0; // 通知事件已处理
        }
        /// </summary>
        ///根据给定的路径，递归查找装配体中的零件，并获取对应的文件名列表
        /// </summary>
        public List<string> GetComponentFileNames(string componentPath, IModelDoc2 activeDoc)
        {
            if (string.IsNullOrEmpty(componentPath))
                throw new ArgumentException("Component path cannot be null or empty.", nameof(componentPath));

            if (activeDoc == null)
                throw new ArgumentNullException(nameof(activeDoc), "Active document cannot be null.");

            // 获取装配体对象
            IAssemblyDoc assemblyDoc = activeDoc as IAssemblyDoc;
            if (assemblyDoc == null)
                throw new InvalidOperationException("The active document is not an assembly.");

            // 分割路径并递归查找
            string[] components = componentPath.Split('/');
            return GetComponentFileNamesRecursive(assemblyDoc, components, 0);
        }//工具方法solidworks
        /// </summary>
        ///根据路径数组，递归处理子组件并获取对应的文件名列表
        /// </summary>
        private List<string> GetComponentFileNamesRecursive(IAssemblyDoc assemblyDoc, string[] components, int index)
        {
            List<string> fileNames = new List<string>();

            if (index >= components.Length)
                return fileNames;

            // 查找当前组件
            IComponent2 component = assemblyDoc.GetComponentByName(components[index]);

            if (component == null)
                throw new Exception($"Component '{components[index]}' not found in assembly.");

            // 获取文件名
            string componentFilePath = component.GetPathName();
            string componentFileName = System.IO.Path.GetFileName(componentFilePath);
            fileNames.Add(componentFileName);

            // 如果当前组件是装配体，递归处理子组件
            IModelDoc2 subModelDoc = (IModelDoc2)component.GetModelDoc2();
            IAssemblyDoc subAssemblyDoc = subModelDoc as IAssemblyDoc;
            if (subAssemblyDoc != null && index < components.Length - 1)
            {
                // 递归获取子组件文件名
                fileNames.AddRange(GetComponentFileNamesRecursive(subAssemblyDoc, components, index + 1));
            }

            return fileNames;
        }//工具方法solidworks
        //返回该对象所属组件，和名字
        public string GetRelativeComponentName(byte[] SelectID)
        {
            ModelDoc2 activeDoc = (ModelDoc2)iSwApp.ActiveDoc;
            object retrievedObject = activeDoc.Extension.GetObjectByPersistReference3(SelectID, out int errors);//通过 SelectID寻找组件
            if (retrievedObject != null)
            {
                // 获取 SelectionMgr，用于处理选择操作
                Component2 owningComponent = null;
                ISelectionMgr selectionMgr = (ISelectionMgr)activeDoc.SelectionManager;

                // 遍历当前选择的对象，查找是否有匹配的对象
                int selCount = selectionMgr.GetSelectedObjectCount2(-1);
                for (int i = 1; i <= selCount; i++)
                {
                    object selectedObj = selectionMgr.GetSelectedObject6(i, -1);

                    // 如果找到匹配的对象，获取其所属的 Component2
                    if (selectedObj != null && selectedObj == retrievedObject)
                    {
                        owningComponent = (Component2)selectionMgr.GetSelectedObjectsComponent2(i);
                        break;
                    }
                }

                // 打印结果
                if (owningComponent != null)
                {
                    return owningComponent.Name2;
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }//工具方法solidworks
        /// <summary>
        /// 用来获取一个组件（或文档）在装配体中的父级路径层级的字符串描述/// 
        /// </summary>
        public string GetParentComponentPath(IComponent2 component, IModelDoc2 activeDoc, bool bUseThisComp = false)
        {
            IModelDoc2 componentDoc;
            if (component == null)
            {
                componentDoc = activeDoc;
            }
            else
            {
                componentDoc = (IModelDoc2)component.GetModelDoc2();
            }

            if (activeDoc.GetType() == (int)swDocumentTypes_e.swDocPART || componentDoc == activeDoc)
            {
                string componentDocName = System.IO.Path.GetFileNameWithoutExtension(activeDoc.GetPathName());
                return componentDocName;
            }

            if (componentDoc == null)
            {
                return "";
            }

            // 获取父级的完整路径
            List<string> parentNames = new List<string>();

            IComponent2 currentComponent = component;
            IComponent2 parentComponent = null;

            while ((parentComponent = currentComponent.GetParent()) != null)
            {
                // 获取父级文件的ModelDoc2对象
                ModelDoc2 parentDoc = parentComponent.GetModelDoc2() as ModelDoc2;
                if (parentDoc != null)
                {
                    string parentFileName = parentDoc.GetPathName();
                    string parentFileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(parentFileName);
                    parentNames.Add(parentFileNameWithoutExtension);
                }

                // 设置当前父级为下一个循环的组件
                currentComponent = parentComponent;
            }

            if (bUseThisComp)
            {
                parentNames.Insert(0, System.IO.Path.GetFileNameWithoutExtension(componentDoc.GetPathName()));
            }

            // 处理当component为B-1时直接返回装配体名A
            if (parentNames.Count == 0)
            {
                // 如果 component 的父级为空，则返回装配体名称
                string assemblyName = System.IO.Path.GetFileNameWithoutExtension(activeDoc.GetPathName());
                return assemblyName;
            }

            // 将父级文件名按层级拼接
            parentNames.Reverse(); // 从顶级父级开始拼接
            return string.Join("/", parentNames);
        }//工具方法solidworks

        //在装配体结构树中查找目标零件的引用
        private IComponent2 FindComponentInSubassembly(IModelDoc2 targetDoc, IComponent2 parentComponent)
        {
            // 获取子组件
            object[] subComponents = (object[])parentComponent.GetChildren();
            foreach (IComponent2 subComponent in subComponents)
            {
                // 获取子组件的ModelDoc2对象
                IModelDoc2 componentDoc = subComponent.GetModelDoc2() as IModelDoc2;

                // 如果当前子组件的ModelDoc2与目标ModelDoc2相同，则返回该子组件
                if (componentDoc != null && componentDoc == targetDoc)
                {
                    return subComponent;
                }

                // 递归查找子组件的子组件
                IComponent2 found = FindComponentInSubassembly(targetDoc, subComponent);
                if (found != null)
                {
                    return found;
                }
            }

            return null;
        }
        #endregion
    }
    /// <summary>
    /// //字典扩展和覆盖
    /// </summary>
    public static class DictionaryExtensions
    {
        public static void Update(this object dictionaryObj, Dictionary<string, object> updates)//工具方法
        {
            if (dictionaryObj is Dictionary<string, object> dictionary)
            {
                foreach (var key in updates.Keys)
                {
                    dictionary[key] = updates[key];
                }
            }
        }
    }

}
